Examining Snow’s 1856 Table VI - Predicted Mortality and Diff-in-Diffs with Population Data

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 extends the analysis for Table VI from Snow’s 1856 “Cholera and the water supply …” using a difference-in-differences framework. This notebook builds on the ideas in the notebook “Snow1856_TableVI_Intro” but is stand-alone can be run separately.

With population data by sub-district and by water supply company (originally published in Simon 1856, “Report on the last two cholera-epidemics of London”), Snow was able to compare mortality at the sub-district level more closely than he could in his 1855 “On the mode of communication …”. In Table VI Snow used estimates of mortality rates for Southwark & Vauxhall versus Lambeth, combined with population fractions by sub-district, to calculate population-weighted predicted mortality by sub-district. Snow’s goal was to show that differences in water supply was the predominant factor - more important than crowding or other factors - in accounting for differences across sub-districts.

Snow, however, did not have the statistical tools and methodology available to us today, and his argument had neither the clarity nor the rigor we would demand today. This notebook uses a more appropriate statistical approach: regression that uses the population by sub-district and water company to simultaneously estimate and test differences across the water companies (and across time). The conclusion (not surprisingly) overwhelmingly supports Snow’s contention that dirty versus clean water is the most important factor in accounting for differences across sub-districts (and across time). As a digression I examine earlier efforts in the literature to address and extend Snow’s Table VI, discussing why those efforts fall short.

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.

# 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
rm(list=ls())    # starts a fresh workspace
#
library(knitr)
options(scipen=5)
# 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") 
# Read in plot functions - see the R code or the notebook 'Snow1855_DiDRegression2_ErrorAnalysis.rmd' for a description of those function
source('SnowPlotFns.r') 
# Read in the data from Snow 1855 "On the mode of communication of cholera"
tableviii <- read.csv(file="Snow1855_TableVIII.csv", header=TRUE, sep=",", skip=5,comment.char="#")
tablexii <- read.csv(file="Snow1855_TableXII.csv", header=TRUE, sep=",", skip=5,comment.char="#")
# Read in the data from John Snow 1856, "Cholera and the water supply in the south district of London in 1854", 
#   These data were copied from the 1936 book "Snow on cholera, being a reprint of two papers" edited by Frost
# Table V by District (for running Poisson & Neg Binomial count regressions)
# Table VI by sub-district (for running Koch & Denike's tests)
# Table I "Showing the results of the Author's personal Inquiry into Twenty-One Sub-Districts"
# Table II "Showing the results of Inquiry made by Mr. Whiting in Eleven Sub-Districts"
# (My "tablei_1856" combines Snow's Tables I & II)
tablei_1856 <- read.csv(file="Snow1856_TableI.csv",
  header=TRUE, sep=",", skip=5,comment.char="#")
tableV_1856 <- read.csv(file="Snow1856_TableV.csv",
  header=TRUE, sep=",", skip=5,comment.char="#")
tableVI_1856 <- read.csv(file="Snow1856_TableVI.csv",
  header=TRUE, sep=",", skip=5,comment.char="#")

Difference-in-Differences Regression with Population Weights

Setting the Scene

In Snow 1856 we have estimated houses and estimated population assigned to the two water supply companies. But there are actually three sources of water: Southwark & Vauxhall Co, Lambeth Co, and “Other” (pump-wells, Thames, ditches). There is considerable variation across sub-districts not only in the proportion supplied by Southwark versus Lambeth, but also in the total proportion supplied by water companies versus “other”.

tablei_1856$combined_pop <- tablei_1856$southwark_pop + tablei_1856$lambeth_pop
tablei_1856[c("subDistrict","pop1851","southwark_pop","lambeth_pop","combined_pop")]

The estimates published in Snow 1856 Tables I and II (displayed above) show that for St. Saviour, Southwark 82.9% was supplied by the Southwark water company, 4.6% by Lambeth, and 87.4% by the two combined. For St. Mary, Newington 21.3% was supplied by the Southwark Company, 39.1% by Lambeth, and only 60.3% by the two combined.

Note in passing that there are problems with the population estimates (which Snow highlighted). Some sub-districts that were in fact not supplied by the Lambeth Company (such as St. Saviour, Southwark) have incorrectly-reported Lambeth population. Some sub-districts (such as St. Mary Magdalen) have a larger combine Southwark + Lambeth population than the 1851 census population.

To account for the variation in observed sub-district mortality we need to measure the population differences for all three sources; Snow in Table VI only accounted for the first two. To do this we can model the mortality rate for a sub-district as the population-weighted average:

\(R_{subdis,yr} = R_S * P_S + R_L^{54} * P_L * I_{yr=1854} + R_L * P_L + R_O * P_O + \delta_{54} * I_{yr=1854} + \epsilon\)

  • \(R_S ...\) = (estimated) mortality rate for Southwark, Lambeth, Other
  • \(P_S ...\) = (observed) population proportion for Southwark, Lambeth, Other
  • \(R_L^{54}\) = (estimated) Lambeth 1854 effect (clean water treatment effect)

To highlight and more easily test the difference between Southwark and Lambeth we can note that \(P_S = 1 - P_L - P_O\), use \(R_S\) as the overall constant, and write

\(R_{subdis,yr} = R_S + (R_L^{54}-R_S) * P_L * I_{yr=1854} + (R_L-R_S) * P_L + (R_O-R_S) * P_O + \delta_{54} * I_{yr=1854} + \epsilon\)

so that the estimated coefficients (\((R_L-R_S)\)) are the difference from the excluded (Southwark) category.

Creating the Data

Just as for the notebook “Snow1855_DiDRegression1” we must stack the data from Snow 1855 Tables VIII and XII and create appropriate indicator variables. Here we also need to merge in the population estimates from Snow 1856 Tables I & II.

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]
# First, re-generate "redgata" after pasting on population fractions. 
# For 1849 and for Southwark-only sub-districts 
# Lambeth population as percent of total (1851) population. Zero out the non-Lambeth sub-districts ("first 12")
# I want three variables:
#  1) Lambeth for both 1849 & 1854 
#  2) Other for both 1849 & 1854
# these two will measure against Southwark for dirty water
#  3) Lambeth for 1854   -  this should measure Lambeth for clean water
x1849$otherperc <- 0
x1854$otherperc <- 0
x1849$lambethperc <- 0
x1854$lambethperc <- 0
x1849$lambethperc54 <- 0
x1854$lambethperc54 <- 0
# This calculates lambeth as percent of TOTAL population. I think this is right for
# measuring the "Lambeth effect" because it gives the proportion of the population treated (with clean Lambeth water)
# which is the variation from 1849 to 1854
x1849$otherperc <- 1 - (tablei_1856[1:28,]$southwark_pop + tablei_1856[1:28,]$lambeth_pop ) /
    tablei_1856[1:28,]$pop1851
x1854$otherperc <- x1849$otherperc
# Variable for only 1954 Lambeth
x1854[13:28,]$lambethperc54 <- tablei_1856[13:28,]$lambeth_pop / tablei_1856[13:28,]$pop1851
x1849$lambethperc <- x1854$lambethperc54
x1854$lambethperc <- x1849$lambethperc
# population per house seems to come in as factor - convert to numeric
x1849$pop_per_house <- as.numeric(as.character(tablei_1856$pop_per_house[1:28]))
x1854$pop_per_house <- as.numeric(as.character(tablei_1856$pop_per_house[1:28]))
regdata <- rbind(x1849,x1854)
regdata

OLS Linear Regressions

With the dataframe “regdata” we can now run various regressions. To start just the simple OLS linear regression.

# Linear with no population density
linpropn <- lm(rate ~ lambethperc54 + lambethperc + otherperc + year, data=regdata )
linpropnrobustse <- coeftest(linpropn, vcov = vcovHC(linpropn))
summary(linpropn)

Call:
lm(formula = rate ~ lambethperc54 + lambethperc + otherperc + 
    year, data = regdata)

Residuals:
    Min      1Q  Median      3Q     Max 
-62.086 -18.678  -2.177  19.836  73.334 

Coefficients:
              Estimate Std. Error t value Pr(>|t|)    
(Intercept)    161.788      9.075  17.827  < 2e-16 ***
lambethperc54 -126.532     27.008  -4.685 2.12e-05 ***
lambethperc    -26.641     19.837  -1.343    0.185    
otherperc     -119.265     14.679  -8.125 9.27e-11 ***
year1854        11.834     11.043   1.072    0.289    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 30.73 on 51 degrees of freedom
Multiple R-squared:  0.678, Adjusted R-squared:  0.6528 
F-statistic: 26.85 on 4 and 51 DF,  p-value: 5.142e-12

The “Lambeth” or clean water effect is the coefficient “lambethperc54” = -126.5 - the mortality per 10,000 for Lambeth company customers, as a difference from Southwark & Vauxhall company customers. The z value of -4.7 indicates that this is statistically significant. The value itself is very large, telling us that in 1854 the mortality rate of Lambeth customers was -127 per 10,000 lower than for Southwark & Vauxhall customers - a very large difference given that the base Southwark & Vauxhall mortality was 162.

The adjusted R-squared tests whether variations in the population proportions and differences in water supply account for much of the observed variation in mortality, exactly what Snow was trying to test. The high R-squared shows that indeed differences in mortality between water suppliers accounts for much of the observed variation.

The population estimates published in 1856 also included housing density estimates. One popular and very reasonable hypothesis was that crowding led to higher cholera mortality. We can test the effect of differences in crowding, within this region of south London, by including housing density as a regressor.

# Linear with population density
linpropn_den <- lm(rate ~ lambethperc54 + lambethperc + otherperc + year
    + pop_per_house , data=regdata)
linpropn_denrobustse <- coeftest(linpropn_den, vcov = vcovHC(linpropn_den))
summary(linpropn_den)

Call:
lm(formula = rate ~ lambethperc54 + lambethperc + otherperc + 
    year + pop_per_house, data = regdata)

Residuals:
   Min     1Q Median     3Q    Max 
-51.80 -20.13  -2.43  17.38  74.56 

Coefficients:
              Estimate Std. Error t value   Pr(>|t|)    
(Intercept)     78.716     42.080   1.871     0.0673 .  
lambethperc54 -126.532     26.229  -4.824 0.00001360 ***
lambethperc    -32.290     19.467  -1.659     0.1034    
otherperc      -96.663     18.126  -5.333 0.00000233 ***
year1854        11.834     10.724   1.103     0.2751    
pop_per_house   11.679      5.785   2.019     0.0489 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 29.84 on 50 degrees of freedom
Multiple R-squared:  0.7023,    Adjusted R-squared:  0.6725 
F-statistic: 23.59 on 5 and 50 DF,  p-value: 4.262e-12

Doing so has virtually effect on the Lambeth coefficient - it is still -126.5. Housing density is marginally significant but adds little to the overall explanatory power of the regression - the Adjusted R-Squared increases from 0.653 to 0.673.

We can also include fixed effects for each sub-district. Including housing density asks “does the difference in density across sub-districts help explain mortality, or reduce the importance of clean water for Lambeth customers?” Including fixed effects asks a dramatically more general question: “are there any differences across sub-districts that help explain mortality or reduce the importance of clean water?” The answer is basically “No”.

# Linear with fixed effects
linpropn_FE <- lm(rate ~ lambethperc54 + lambethperc + otherperc + year
    + subDistrict, data=regdata )
linpropn_FErobustse <- coeftest(linpropn_FE, vcov = vcovHC(linpropn_FE))
summary(linpropn_FE)

Call:
lm(formula = rate ~ lambethperc54 + lambethperc + otherperc + 
    year + subDistrict, data = regdata)

Residuals:
   Min     1Q Median     3Q    Max 
-33.59 -10.09   0.00  10.09  33.59 

Coefficients: (2 not defined because of singularities)
                                    Estimate Std. Error t value   Pr(>|t|)    
(Intercept)                         129.8562   117.2235   1.108     0.2781    
lambethperc54                      -126.5322    20.1596  -6.277 0.00000121 ***
lambethperc                           7.4768   187.4058   0.040     0.9685    
otherperc                            -5.9294   312.1370  -0.019     0.9850    
year1854                             11.8339     8.2426   1.436     0.1630    
subDistrictBorough Road              71.2452    38.0904   1.870     0.0727 .  
subDistrictBrixton                  -54.5466    76.2662  -0.715     0.4809    
subDistrictCamberwell                 0.7515    33.1530   0.023     0.9821    
subDistrictChristchurch, Southwark   25.4153    40.1630   0.633     0.5324    
subDistrictClapham                  -46.2542    69.5678  -0.665     0.5120    
subDistrictKennington (1st)         -27.1488    29.9296  -0.907     0.3727    
subDistrictKennington (2nd)         -39.1963    34.0302  -1.152     0.2599    
subDistrictKent Road                 -1.3322    53.3028  -0.025     0.9803    
subDistrictLambeth Church (1st)     -16.1376    39.8275  -0.405     0.6887    
subDistrictLambeth Church (2nd)      35.8242    34.2336   1.046     0.3050    
subDistrictLeather Market            15.6610   114.2659   0.137     0.8920    
subDistrictLondon Road               -0.5430    66.8909  -0.008     0.9936    
subDistrictPeckham                  -63.2201   105.0052  -0.602     0.5523    
subDistrictPutney                  -113.8284   193.0655  -0.590     0.5606    
subDistrictRotherhithe               44.1273    29.1176   1.515     0.1417    
subDistrictSt. George, Camberwell   -17.1792    70.6785  -0.243     0.8099    
subDistrictSt. James, Bermondsey     24.3172   199.3923   0.122     0.9039    
subDistrictSt. John, Horsleydown     14.9186    65.2125   0.229     0.8208    
subDistrictSt. Mary Magdalen         43.3061   191.8700   0.226     0.8232    
subDistrictSt. Mary, Newington      -27.8881    82.4176  -0.338     0.7378    
subDistrictSt. Olave, Southwark      62.0648   146.2666   0.424     0.6748    
subDistrictSt. Peter, Walworth       24.8751    19.1664   1.298     0.2057    
subDistrictSt. Saviour, Southwark    30.8852    80.1788   0.385     0.7032    
subDistrictTrinity, Newington        13.4145    19.7972   0.678     0.5040    
subDistrictWandsworth               -49.3044   165.1611  -0.299     0.7677    
subDistrictWaterloo Road (1st)            NA         NA      NA         NA    
subDistrictWaterloo Road (2nd)            NA         NA      NA         NA    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 22.93 on 26 degrees of freedom
Multiple R-squared:  0.9086,    Adjusted R-squared:  0.8066 
F-statistic: 8.907 on 29 and 26 DF,  p-value: 0.0000001375

The Adjusted R-Squared increases from 0.653 to 0.807, but the value of the Lambeth effect is unchanged and in fact is now estimated even more precisely: t value -6.3. Yes there are differences in mortality across sub-districts that are not explained only by differences in water supplier, but water supply still has a dramatically large and precisely-estimated effect.

Count - Linear Regressions (Poisson & Negative Binomial Regressions)

The OLS regression above is not really appropriate because observed variables are counts - positive and integer-valued rather than the continuous rates used in the above regessions. For the observed counts the regression residuals cannot be continuous normal variables. We need to turn to Poisson or Negative Binomial regression.

The default for counts (Poisson and Negative Binomial regressions) is to estimate in log form, as discussed below. Here, howerver, we will use a linear relation between the rates and regressors:

\(R_{subdis,yr} = R_S + (R_L^{54}-R_S) * P_L * I_{yr=1854} + (R_L-R_S) * P_L + (R_O-R_S) * P_O + \delta_{54} * I_{yr=1854}\)

The rate is the count divided by the population:

\(R_{subdis,yr} = Count_{subdis,yr} / Pop_{subdis,yr}\)

To transform from the rate equation to counts we need to multiply all the regressors by the population:

\(Count_{subdis,yr} = R_S*Pop_{subdis,yr} + (R_L^{54}-R_S) * \tilde{P}_L * I_{yr=1854} + (R_L-R_S) * \tilde{P}_L + (R_O-R_S) * \tilde{P}_O + \delta_{54} * \tilde{I}_{yr=1854} + \epsilon\)

where I am using \(\tilde{P_L} ...\) to mean \(P_L * Pop_{subdis,yr}\). (This also means running the regression with no intercept and using \(Pop_{subdis,yr}\) as a regressor.)

The following code chunk runs a Poisson and Negative Binomial regression but displays only the Negative Binomial, since as usual the Poisson regression shows overdispersion (does not fit the data well) so that we cannot rely on the Poisson standard errors.

# For running linear count regressions, we need to weight all the regressors by the population (since we can't use the "offset()" method)
regdata_lin <- regdata 
regdata_lin$yearind <- 1.0*(regdata$year == "1854")
regdata_lin$pop1851 <- regdata_lin$pop1851 / 10000
regdata_lin[,c("yearind","otherperc","lambethperc","lambethperc54","pop_per_house")] <-
    regdata_lin[,c("yearind","otherperc","lambethperc","lambethperc54","pop_per_house")] * regdata_lin$pop1851
# Poisson regression with linear (identity) link function
pois1propn_lin <- glm(deaths ~ pop1851 + lambethperc54 + lambethperc + otherperc + yearind
    - 1 , family=poisson(link="identity"), data=regdata_lin)
pois1propn_linrobustse <- coeftest(pois1propn_lin, vcov = vcovHC(pois1propn_lin))
#summary(pois1propn_lin)
#logLik(pois1propn_lin)
# Poisson FE regression with linear (identity) link function
pois2propn_lin <- glm(deaths ~ pop1851 + lambethperc54 + lambethperc + otherperc + yearind
    +subDistrict - 1 , family=poisson(link="identity"), data=regdata_lin)
pois2propn_linrobustse <- coeftest(pois2propn_lin, vcov = vcovHC(pois2propn_lin))
#summary(pois2propn_lin)
#logLik(pois2propn_lin)
# Negative Binomial with linear (identity) link function
nb1propn_lin <- glm.nb(deaths ~ pop1851 + lambethperc54 + lambethperc + otherperc + yearind
     - 1, link = identity, data = regdata_lin)
nb1propn_linrobustse <- coeftest(nb1propn_lin, vcov = vcovHC(nb1propn_lin))
#summary(nb1propn_lin)
#logLik(nb1propn_lin)
# Negative Binomial with linear (identity) link function & population density
nb1propn_linden <- glm.nb(deaths ~ pop1851 + lambethperc54 + lambethperc + otherperc + yearind
     + pop_per_house - 1, link = identity, data = regdata_lin)
nb1propn_lindenrobustse <- coeftest(nb1propn_linden, vcov = vcovHC(nb1propn_linden))
#summary(nb1propn_linden)
#logLik(nb1propn_linden)
# Finally, FEs
nb2propn_lin <- glm.nb(deaths ~ pop1851 + lambethperc54 + lambethperc + otherperc + yearind
    + subDistrict - 1, link = identity, data=regdata_lin)
nb2propn_linrobustse <- coeftest(nb2propn_lin, vcov = vcovHC(nb2propn_lin))
#summary(nb2propn_lin)
#logLik(nb2propn_lin)
summary(nb1propn_linden)

Call:
glm.nb(formula = deaths ~ pop1851 + lambethperc54 + lambethperc + 
    otherperc + yearind + pop_per_house - 1, data = regdata_lin, 
    link = identity, init.theta = 15.5054521)

Deviance Residuals: 
    Min       1Q   Median       3Q      Max  
-2.4701  -0.8190  -0.1024   0.5172   2.6013  

Coefficients:
              Estimate Std. Error z value     Pr(>|z|)    
pop1851        100.586     36.057   2.790      0.00528 ** 
lambethperc54 -131.311     23.348  -5.624 0.0000000186 ***
lambethperc    -49.446     23.158  -2.135      0.03275 *  
otherperc     -127.752     15.198  -8.406      < 2e-16 ***
yearind         12.379      9.570   1.294      0.19582    
pop_per_house   10.493      4.916   2.134      0.03280 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

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

    Null deviance:    Inf  on 56  degrees of freedom
Residual deviance: 60.315  on 50  degrees of freedom
AIC: 601.17

Number of Fisher Scoring iterations: 1

              Theta:  15.51 
          Std. Err.:  3.37 

 2 x log-likelihood:  -587.17 

This linear Negative Binomial regression gives results similar to the linear OLS regression above.

Count - Log Regressions (Poisson & Negative Binomial Regressions)

The linear count regressions incorporate the assumption that the random variables are counts, but linearity is not necessarily a good assumption. It imposes the assumption that the treatment effect reduces mortality rates by a fixed amount independent of the base mortality level. A proportional or ratio expression would be more reasonable. Unfortunately the standard estimation routines are based on a linear-in-logs form:

\(ln(R_{subdis,yr}) = R_S + (R_L^{54}-R_S) * P_L * I_{yr=1854} + (R_L-R_S) * P_L + (R_O-R_S) * P_O + \delta_{54} * I_{yr=1854} + \epsilon\)

It is thus difficult to impose exactly the linear relation between the rate and the population fractions. (We would need a non-linear Poisson and Negative Binomial fitting routine.) In spite of this we can run the count regressions and we find essentially the same as the linear regressions: water supply is dramatically important and the effect on mortality dramatically large.

The following code chunk runs a variety of Poisson and Negative Binomial regressions but displays only the Negative Binomial with housing density.

# Poisson with no FE and no housing density
pois1propn <- glm(deaths ~ lambethperc54 + lambethperc + otherperc + year
    + offset(log(pop1851)), family=poisson, data=regdata)
pois1propnrobustse <- coeftest(pois1propn, vcov = vcovHC(pois1propn))
#summary(pois1propn)
#logLik(pois1propn)
# Poisson with housing density
pois1propn_den <- glm(deaths ~ lambethperc54 + lambethperc + otherperc + year
    + pop_per_house + offset(log(pop1851)), family=poisson, data=regdata)
pois1propn_denrobustse <- coeftest(pois1propn_den, vcov = vcovHC(pois1propn_den))
#summary(pois1propn_den)
#logLik(pois1propn_den)
# Poisson with different rates by sub-district (fixed effects)
pois2propn <- glm(deaths ~ lambethperc54 + lambethperc + otherperc + year
    + subDistrict + offset(log(pop1851)), family=poisson, data=regdata)
pois2propnrobustse <- coeftest(pois2propn, vcov = vcovHC(pois2propn))
#summary(pois2propn)
#logLik(pois2propn)
# Negative Binomial with no FE and no housing density
nb1propn <- glm.nb(deaths ~ lambethperc54 + lambethperc + otherperc + year
     + offset(log(pop1851)), data=regdata)
nb1propnrobustse <- coeftest(nb1propn, vcov = vcovHC(nb1propn))
#summary(nb1propn)
#logLik(nb1propn)
# Also run with housing density
nb1propn_den <- glm.nb(deaths ~ lambethperc54 + lambethperc + otherperc + year
    + pop_per_house + offset(log(pop1851)), data=regdata)
nb1propn_denrobustse <- coeftest(nb1propn_den, vcov = vcovHC(nb1propn_den))
#summary(nb1propn_den)
#logLik(nb1propn_den)
# Finally, FEs
nb2propn <- glm.nb(deaths ~ lambethperc54 + lambethperc + otherperc + year
    + subDistrict + offset(log(pop1851)), data=regdata)
nb2propnrobustse <- coeftest(nb2propn, vcov = vcovHC(nb2propn))
#summary(nb2propn)
#logLik(nb2propn)
summary(nb1propn_den)

Call:
glm.nb(formula = deaths ~ lambethperc54 + lambethperc + otherperc + 
    year + pop_per_house + offset(log(pop1851)), data = regdata, 
    init.theta = 11.54058123, link = log)

Deviance Residuals: 
     Min        1Q    Median        3Q       Max  
-2.97050  -0.70669  -0.06242   0.58061   2.01883  

Coefficients:
              Estimate Std. Error z value    Pr(>|z|)    
(Intercept)   -4.57160    0.43052 -10.619     < 2e-16 ***
lambethperc54 -1.38906    0.26946  -5.155 0.000000254 ***
lambethperc   -0.22167    0.19759  -1.122       0.262    
otherperc     -0.98755    0.18964  -5.207 0.000000191 ***
year1854       0.12547    0.10999   1.141       0.254    
pop_per_house  0.06625    0.05925   1.118       0.263    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

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

    Null deviance: 154.987  on 55  degrees of freedom
Residual deviance:  61.328  on 50  degrees of freedom
AIC: 617.31

Number of Fisher Scoring iterations: 1

              Theta:  11.54 
          Std. Err.:  2.48 

 2 x log-likelihood:  -603.315 

The result for the Negative Binomial with housing density is, again, that the effect of clean water (the Lambeth effect) is large and statistically significant (coefficient -1.389, ratio effect 4.01, z ratio -5.16). The regression fits the data reasonably well when measured by the Residual Deviance.

Populating Table with Summary Statistics

I use these tables to summarize the diff-in-diff regressions, but do not display them here. You can if you wish.

First, a code chunk for the linear regressions (but also including the Negative Binomial with population density)

# First, create the dataframes for prediction. "predict" can take in a dataframe but for some reason it only
# seems to work with a dataframe from a regression (at least I couldn't get it to work any other way). 
# The idea is to take a "model.dataframe" from one of the regressions (just the first three rows) and
# then manually insert the population proportions, years, etc. that we want to predict:
#  - Southwark rate, 1854, average housing density (1st row, Lambeth and "Other" population proportions 0)
#  - Lambeth rate, 1854, average housing density (2nd row Lambethperc=1 and lambethperc54=1)
#  - "Other" rate, 1854, average housing density (3rd row, otherperc=1)
# The idea is to take the dataframe from a fitted model, then over-write the indicators for "Lambeth", "Other"
# We need population, and if we put in 10,000 then the counts will be per 10,000 people which is the way we 
# want to quote rates. 
regdata_pred <- model.frame(nb1propn_linden)[1:3,]
regdata_pred$lambethperc <- c(0,1,0)  # Population proportion for Lambeth
regdata_pred$lambethperc54 <- c(0,1,0)  # Population proportion for Lambeth 1954
regdata_pred$otherperc <- c(0,0,1)   # Population proportion for "Other"
regdata_pred$pop_per_house <- mean(regdata$pop_per_house)  # set population per house to the mean
regdata_pred$year <- "1854"   # Year to 1854
regdata_pred$`offset(log(pop1851))` <- log(10000)  # Force population to be 10,000
regdata_pred$pop1851 <- 10000    # Force population to be 10,000
# Slight difference for predicting with linear count models, where we need to enter the
# "10,000" population as "1" (since we estimated parameters per 10,000)
regdata_predlin <- regdata_pred
regdata_predlin$pop1851 <- 1
regdata_predlin$yearind <- 1
# --------------------- #
# Create table with regression results (diff-in-diffs estimate) using robust SEs
# for all except the NB1 (Negative Binomial without sub-district fixed effects)
regtabledid1856lin <- matrix(0,nrow=16,ncol=9)
colnames(regtabledid1856lin) <- c("Lin OLS","Lin Poisson","Lin Poiss FE",
                                  "Lin Neg Binom","Lin NB, House","Lin NB, FE",
                                  "Log NB","Log NB H den","log NB FE")
rownames(regtabledid1856lin) <- c("Lambeth 1854 effect","SE","z value",
    "lambeth perc","z value","other perc","z value","1854","z value",
    "pop density","z value","Adj Rsq / resid dev",  "Resid Dev p-value",
    "Southwark 1854 rate","Lambeth 1854 rate","Other rate")
# Populate the table from the regressions
# First, define rows to put data into
xteffect <- c(1,2,3)
xresidev <- 12
xresidevpv <- 13
xlambeth <- c(4,5)
xother <- c(6,7)
xyear <- c(8,9)
xhden <- c(10,11)
xmortality <- c(14,15,16)
# Linear no population density
xrow <- 1
regtabledid1856lin[xteffect,xrow] <- summary(linpropn)$coefficients[2,c(1,2,3)]
regtabledid1856lin[xresidev,xrow] <- summary(linpropn)$adj.r.squared
regtabledid1856lin[xlambeth,xrow] <- summary(linpropn)$coefficients[3,c(1,3)]
regtabledid1856lin[xother,xrow] <- summary(linpropn)$coefficients[4,c(1,3)]
regtabledid1856lin[xyear,xrow] <- summary(linpropn)$coefficients[5,c(1,3)]
regtabledid1856lin[xmortality,xrow] <- predict(linpropn,newdata=regdata_pred)
# Poisson, linear form
xrow <- 2
regtabledid1856lin[xteffect,xrow] <- summary(pois1propn_lin)$coefficients[2,c(1,2,3)]
regtabledid1856lin[xresidev,xrow] <- summary(pois1propn_lin)$deviance
regtabledid1856lin[xlambeth,xrow] <- summary(pois1propn_lin)$coefficients[3,c(1,3)]
regtabledid1856lin[xother,xrow] <- summary(pois1propn_lin)$coefficients[4,c(1,3)]
regtabledid1856lin[xyear,xrow] <- summary(pois1propn_lin)$coefficients[5,c(1,3)]
regtabledid1856lin[xresidevpv,xrow] <- (1-pchisq(summary(pois1propn_lin)$deviance,summary(pois1propn_lin)$df.residual))
regtabledid1856lin[xmortality,xrow] <- predict(pois1propn_lin,newdata=regdata_predlin)
# Negative Binomial FE, linear form
xrow <- 3
regtabledid1856lin[xteffect,xrow] <- summary(pois2propn_lin)$coefficients[2,c(1,2,3)]
regtabledid1856lin[xresidev,xrow] <- summary(pois2propn_lin)$deviance
regtabledid1856lin[xlambeth,xrow] <- summary(pois2propn_lin)$coefficients[3,c(1,3)]
regtabledid1856lin[xother,xrow] <- summary(pois2propn_lin)$coefficients[4,c(1,3)]
regtabledid1856lin[xyear,xrow] <- summary(pois2propn_lin)$coefficients[5,c(1,3)]
regtabledid1856lin[xresidevpv,xrow] <- (1-pchisq(summary(pois2propn_lin)$deviance,summary(pois2propn_lin)$df.residual))
# Negative Binomial, linear form
xrow <- 4
regtabledid1856lin[xteffect,xrow] <- summary(nb1propn_lin)$coefficients[2,c(1,2,3)]
regtabledid1856lin[xresidev,xrow] <- summary(nb1propn_lin)$deviance
regtabledid1856lin[xlambeth,xrow] <- summary(nb1propn_lin)$coefficients[3,c(1,3)]
regtabledid1856lin[xother,xrow] <- summary(nb1propn_lin)$coefficients[4,c(1,3)]
regtabledid1856lin[xyear,xrow] <- summary(nb1propn_lin)$coefficients[5,c(1,3)]
regtabledid1856lin[xresidevpv,xrow] <- (1-pchisq(summary(nb1propn_lin)$deviance,summary(nb1propn_lin)$df.residual))
regtabledid1856lin[xmortality,xrow] <- predict(nb1propn_lin,newdata=regdata_predlin)
# Negative Binomial population density, linear form
xrow <- 5
regtabledid1856lin[xteffect,xrow] <- summary(nb1propn_linden)$coefficients[2,c(1,2,3)]
regtabledid1856lin[xresidev,xrow] <- summary(nb1propn_linden)$deviance
regtabledid1856lin[xlambeth,xrow] <- summary(nb1propn_linden)$coefficients[3,c(1,3)]
regtabledid1856lin[xother,xrow] <- summary(nb1propn_linden)$coefficients[4,c(1,3)]
regtabledid1856lin[xyear,xrow] <- summary(nb1propn_linden)$coefficients[5,c(1,3)]
regtabledid1856lin[xhden,xrow] <- summary(nb1propn_linden)$coefficients[6,c(1,3)]
regtabledid1856lin[xresidevpv,xrow] <- (1-pchisq(summary(nb1propn_linden)$deviance,summary(nb1propn_linden)$df.residual))
regtabledid1856lin[xmortality,xrow] <- predict(nb1propn_linden,newdata=regdata_predlin)
# Negative Binomial FE, logarithmic form
xrow <- 6
regtabledid1856lin[xteffect,xrow] <- summary(nb2propn_lin)$coefficients[2,c(1,2,3)]
regtabledid1856lin[xresidev,xrow] <- summary(nb2propn_lin)$deviance
regtabledid1856lin[xlambeth,xrow] <- summary(nb2propn_lin)$coefficients[3,c(1,3)]
regtabledid1856lin[xother,xrow] <- summary(nb2propn_lin)$coefficients[4,c(1,3)]
regtabledid1856lin[xyear,xrow] <- summary(nb2propn_lin)$coefficients[5,c(1,3)]
regtabledid1856lin[xresidevpv,xrow] <- (1-pchisq(summary(nb2propn_lin)$deviance,summary(nb2propn_lin)$df.residual))
# Negative Binomial, logarithmic form
xrow <- 7
regtabledid1856lin[xteffect,xrow] <- summary(nb1propn)$coefficients[2,c(1,2,3)]
regtabledid1856lin[xresidev,xrow] <- summary(nb1propn)$deviance
regtabledid1856lin[xlambeth,xrow] <- summary(nb1propn)$coefficients[3,c(1,3)]
regtabledid1856lin[xother,xrow] <- summary(nb1propn)$coefficients[4,c(1,3)]
regtabledid1856lin[xyear,xrow] <- summary(nb1propn)$coefficients[5,c(1,3)]
regtabledid1856lin[xresidevpv,xrow] <- (1-pchisq(summary(nb1propn)$deviance,summary(nb1propn)$df.residual))
regtabledid1856lin[xmortality,xrow] <- exp(predict(nb1propn,newdata=regdata_pred))
# Negative Binomial population density, logarithmic form
xrow <- 8
regtabledid1856lin[xteffect,xrow] <- summary(nb1propn_den)$coefficients[2,c(1,2,3)]
regtabledid1856lin[xresidev,xrow] <- summary(nb1propn_den)$deviance
regtabledid1856lin[xlambeth,xrow] <- summary(nb1propn_den)$coefficients[3,c(1,3)]
regtabledid1856lin[xother,xrow] <- summary(nb1propn_den)$coefficients[4,c(1,3)]
regtabledid1856lin[xyear,xrow] <- summary(nb1propn_den)$coefficients[5,c(1,3)]
regtabledid1856lin[xhden,xrow] <- summary(nb1propn_den)$coefficients[6,c(1,3)]
regtabledid1856lin[xresidevpv,xrow] <- (1-pchisq(summary(nb1propn_den)$deviance,summary(nb1propn_den)$df.residual))
regtabledid1856lin[xmortality,xrow] <- exp(predict(nb1propn_den,newdata=regdata_pred))
# Negative Binomial FE, logarithmic form
xrow <- 9
regtabledid1856lin[xteffect,xrow] <- summary(nb2propn)$coefficients[2,c(1,2,3)]
regtabledid1856lin[xresidev,xrow] <- summary(nb2propn)$deviance
regtabledid1856lin[xlambeth,xrow] <- summary(nb2propn)$coefficients[3,c(1,3)]
regtabledid1856lin[xother,xrow] <- summary(nb2propn)$coefficients[4,c(1,3)]
regtabledid1856lin[xyear,xrow] <- summary(nb2propn)$coefficients[5,c(1,3)]
regtabledid1856lin[xresidevpv,xrow] <- (1-pchisq(summary(nb2propn)$deviance,summary(nb2propn)$df.residual))
kable(regtabledid1856lin[c(1,3,9,10,12,13),c(2,4,5)],digits=3, caption = "Summary - Diff-in-Diffs Comparison Using Population Proportions",format='pandoc')
Summary - Diff-in-Diffs Comparison Using Population Proportions
Lin Poisson Lin Neg Binom Lin NB, House
Lambeth 1854 effect -141.375 -118.456 -131.311
z value -20.005 -4.983 -5.624
z value 5.222 0.573 1.294
pop density 0.000 0.000 10.493
Adj Rsq / resid dev 712.188 60.115 60.315
Resid Dev p-value 0.000 0.179 0.151

Note the very low predicted Lambeth mortality rate for the “Linear Negative Binomial” model. I believe this is an artifact of the linear functional form and the effect of housing density. Linearity forces the same additive effect on mortality rate, which is probably not appropriate. Southwark rates are on the order of 170 and Lambeth on the order of 20. With the estimated density coefficient roughly 10, if housing density is one percentage point lower that would be a modest effect on the Southwark rate (from 170 to 160) but a huge effect on Lambeth (from 20 to 10). Linearity is probably not a good assumption - the effect is more likely to be multiplicative.

The problem shows up particularly because of the positive correlation between density and proportion of Lambeth customers: It appears that sub-districts with a higher proportion of Lambeth customers are also higher housing density (correlation 0.71).

The numbers quoted in the table are the predicted rate for “average” housing density, 6.83 people per house. Reporting the predicted rate for “average” density probably pushes the mortality for Lambeth customers below what it should be. Using a larger housing density would give a more appropriate prediction. Note that the linear Negative Binomial regression run without housing density predicts a rate of 15.3. The logarithmic form of the Negative Binomial, which we think should be better behaved because it is based on multiplicative effects, predicts 38.9 for no housing density, and 36.8 with (average) housing density.

Below is a code chunk for the various permutations of count regressions with population proportions, six regressions in total:

  • Poisson and Negative Binomial
  • For each, no population density, yes population density, sub-district fixed effects.
# Create table with regression results (diff-in-diffs estimate) using robust SEs
# for all except the NB1 (Negative Binomial without sub-district fixed effects)
regtabledid1856 <- matrix(0,nrow=21,ncol=6)
colnames(regtabledid1856) <- c("Poiss","Poiss pop","PoissFE","NB","NB pop","NB FE")
rownames(regtabledid1856) <- c("Lambeth 1854 effect","SE","z value","p-value",
    "robust SE","z value","ratio effect",
    "lambeth perc","SE","z value","p-value","other perc","SE","z value","p-value",
    "theta","resid dev","pop den","SE","z value","p-value")
# Populate the table from the regressions
# Poiss no population density
regtabledid1856[c(1,2,3,4),1] <- summary(pois1propn)$coefficients[2,c(1,2,3,4)]
regtabledid1856[c(5,6),1] <- pois1propnrobustse[2,c(2,3)]
regtabledid1856[7,1] <- exp(regtabledid1856[1,1])
regtabledid1856[c(8,9,10,11),1] <- summary(pois1propn)$coefficients[3,c(1,2,3,4)]
regtabledid1856[c(12,13,14,15),1] <- summary(pois1propn)$coefficients[4,c(1,2,3,4)]
regtabledid1856[17,1] <- summary(pois1propn)$deviance
# Poiss Population density
regtabledid1856[c(1,2,3,4),2] <- summary(pois1propn_den)$coefficients[2,c(1,2,3,4)]
regtabledid1856[c(5,6),2] <- pois1propn_denrobustse[2,c(2,3)]
regtabledid1856[7,2] <- exp(regtabledid1856[1,2])
regtabledid1856[c(8,9,10,11),2] <- summary(pois1propn_den)$coefficients[3,c(1,2,3,4)]
regtabledid1856[c(12,13,14,15),2] <- summary(pois1propn_den)$coefficients[4,c(1,2,3,4)]
regtabledid1856[17,2] <- summary(pois1propn_den)$deviance
regtabledid1856[c(18,19,20,21),2] <- summary(pois1propn_den)$coefficients[5,c(1,2,3,4)]
# Poiss Fixed Effects
regtabledid1856[c(1,2,3,4),3] <- summary(pois2propn)$coefficients[2,c(1,2,3,4)]
regtabledid1856[c(5,6),3] <- pois2propnrobustse[2,c(2,3)]
regtabledid1856[7,3] <- exp(regtabledid1856[1,3])
regtabledid1856[c(8,9,10,11),3] <- summary(pois2propn)$coefficients[3,c(1,2,3,4)]
regtabledid1856[c(12,13,14,15),3] <- summary(pois2propn)$coefficients[4,c(1,2,3,4)]
regtabledid1856[17,3] <- summary(pois2propn)$deviance
# NB no population density
regtabledid1856[c(1,2,3,4),4] <- summary(nb1propn)$coefficients[2,c(1,2,3,4)]
regtabledid1856[c(5,6),4] <- nb1propnrobustse[2,c(2,3)]
regtabledid1856[7,4] <- exp(regtabledid1856[1,3])
regtabledid1856[c(8,9,10,11),4] <- summary(nb1propn)$coefficients[3,c(1,2,3,4)]
regtabledid1856[c(12,13,14,15),4] <- summary(nb1propn)$coefficients[4,c(1,2,3,4)]
regtabledid1856[16,4] <- summary(nb1propn)$theta
regtabledid1856[17,4] <- summary(nb1propn)$deviance
# NB population density & water company percent
regtabledid1856[c(1,2,3,4),5] <- summary(nb1propn_den)$coefficients[2,c(1,2,3,4)]
regtabledid1856[c(5,6),5] <- nb1propn_denrobustse[2,c(2,3)]
regtabledid1856[7,5] <- exp(regtabledid1856[1,5])
regtabledid1856[c(8,9,10,11),5] <- summary(nb1propn_den)$coefficients[3,c(1,2,3,4)]
regtabledid1856[c(12,13,14,15),5] <- summary(nb1propn_den)$coefficients[4,c(1,2,3,4)]
regtabledid1856[16,5] <- summary(nb1propn_den)$theta
regtabledid1856[17,5] <- summary(nb1propn_den)$deviance
regtabledid1856[c(18,19,20,21),5] <- summary(nb1propn_den)$coefficients[5,c(1,2,3,4)]
# NB FEs
regtabledid1856[c(1,2,3,4),6] <- summary(nb2propn)$coefficients[2,c(1,2,3,4)]
regtabledid1856[c(5,6),6] <- nb2propnrobustse[2,c(2,3)]
regtabledid1856[7,6] <- exp(regtabledid1856[1,6])
regtabledid1856[c(8,9,10,11),6] <- summary(nb2propn)$coefficients[3,c(1,2,3,4)]
regtabledid1856[c(12,13,14,15),6] <- summary(nb2propn)$coefficients[4,c(1,2,3,4)]
regtabledid1856[16,6] <- summary(nb2propn)$theta
regtabledid1856[17,6] <- summary(nb2propn)$deviance

Plots For Poisson Error Analasys - Showing too much variation

The Poisson regressions do not account for enough of the variation - the data seem to show that there is more variation than would be accounted for by constant mortality rates (constant for each supplier - Southwark & Vauxhall Company, Lambeth Company, and “Other”), even if we allow each sub-district to vary. The data seem to show that there is some random variation in mortality across the years and sub-districts, but that even so there is a large treatment effect for Lambeth Company’s clean water supply in 1854.

xfamily <- preperrdata(pois1propn_lin,single="continuous",link="linear")  # this function modifies global data
#pdf(paste("../paper/figures/errbar_","pois1_didcontlin","cpdf",sep=""))
  plot3(x1849,x1854,"SouthwarkVauxhall",paste("First-12 Southwark-only ",xfamily," 1849vs1854 "))

#dev.off()
#pdf(paste("../paper/figures/errbar_","pois1_didcontlin","dpdf",sep=""))
  plot3(x1849,x1854,"SouthwarkVauxhall_Lambeth",paste("Next-16 Jointly-Supplied ",xfamily," 1849vs1854 "))

#dev.off()

First, we can look at the most basic Poisson regression (done in logarithmic form), including a treatment effect, a year effect, and a Southwark-versus-Lambeth effect for 1849. (This uses the plot functions in “SnowPlotFns.r”.) The red circles are the 1849 rates. The blue diamonds are 1854 rates but adjusted for the 1854 effect and the treatment effect - in other words made comparable to the 1849 rates. The empty circles are the 1849 predicted rates, with approximate 95% error bars.

This Poisson regression does not fit the data - many observations (33 out of 56 or 59%) are outside the 95% confidence bands. There is simply more variation across sub-districts than could be accounted for with a constant rate for each of the three suppliers.

xfamily <- preperrdata(pois2propn_lin,"continuous",link="linear")  # this function modifies global data
#pdf(paste("../paper/figures/errbar_","pois2_didcontlin","cpdf",sep=""))
  plot3(x1849,x1854,"SouthwarkVauxhall",paste("First-12 Southwark-only FE",xfamily," 1849vs1854 "))

#dev.off()
#pdf(paste("../paper/figures/errbar_","pois2_didcontlin","dpdf",sep=""))
  plot3(x1849,x1854,"SouthwarkVauxhall_Lambeth",paste("Next-16 Jointly-Supplied FE",xfamily," 1849vs1854 "))

#dev.off()

A very reasonable alternative is that rates vary across sub-districts - each sub-district has it’s own rate. This is a fixed effects model, a fixed-coefficient model for rate variation across sub-districts. This explanation does not fit the data well, because there is still too much variation, in this case variation across years but within sub-districts. There are roughly 18 out of 56 or 32% of observations outside the 95% confidence bands.

xfamily <- preperrdata(nb1propn_lin,"continuous",link="linear")  # this function modifies global data
#pdf(paste("../paper/figures/errbar_","nb1_didcontlin","cpdf",sep=""))
  plot3(x1849,x1854,"SouthwarkVauxhall",paste("First-12 Southwark-only ",xfamily," 1849vs1854 "))

#dev.off()
#pdf(paste("../paper/figures/errbar_","nb1_didcontlin","dpdf",sep=""))
  plot3(x1849,x1854,"SouthwarkVauxhall_Lambeth",paste("Next-16 Jointly-Supplied ",xfamily," 1849vs1854 "))

#dev.off()

A third alternative is that mortality rates vary across sub-districts and years in a random manner. A Negative Binomial model is a Gamma-mixture model of Poissons - individuals each have a Poisson intensity for mortality, but the Poisson intensities are distributed across the population according to a Gamma distribution, with the variance of the Gamma parameter to be estimated.

This figure shows the results, and this model fits the data reasonably well. There are 3 out of 56 or 5.45 of the observations outside the approximate 95% confidence bands.

Conclusion - Snow was Right - Clean Water Matters

Using the population by sub-district to measure the fraction of customers supplied by the Southwark & Vauxhall Company, the Lambeth Company, and Other (wells etc.) strongly supports Snow’s contention both that the actual and predicted mortality “bear a close relation” and that nature of the water supply exerts an “overwhelming influence”.

LS0tCnRpdGxlOiAiSm9obiBTbm93IFByb2plY3QgLSAxODU2IFRhYmxlIFZJIGFuZCBEaUQgRXh0ZW5zaW9uIgphdXRob3I6ICJbVGhvbWFzIENvbGVtYW5dKGh0dHA6Ly93d3cuaGlsZXJ1bi5vcmcvZWNvbikiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KIyBFeGFtaW5pbmcgU25vdydzIDE4NTYgVGFibGUgVkkgLSBQcmVkaWN0ZWQgTW9ydGFsaXR5IGFuZCBEaWZmLWluLURpZmZzIHdpdGggUG9wdWxhdGlvbiBEYXRhCgojIyMjIFNlZSAiQ2F1c2FsaXR5IGluIHRoZSBUaW1lIG9mIENob2xlcmEiIHdvcmtpbmcgcGFwZXIgYXQgaHR0cHM6Ly9wYXBlcnMuc3Nybi5jb20vYWJzdHJhY3Q9MzI2MjIzNCBhbmQgbXkgW0pvaG4gU25vdyBwcm9qZWN0IHdlYnNpdGVdKGh0dHA6Ly93d3cuaGlsZXJ1bi5vcmcvZWNvbi9wYXBlcnMvc25vdykKCiMjIyMgVGhpcyBub3RlYm9vayBpcyBsaWNlbnNlZCB1bmRlciB0aGUgW0JTRCAyLUNsYXVzZSBMaWNlbnNlXShodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0yLUNsYXVzZSkKCiMjIyBJbnRyb2R1Y3Rpb24KClRoaXMgbm90ZWJvb2sgZXh0ZW5kcyB0aGUgYW5hbHlzaXMgZm9yIFRhYmxlIFZJIGZyb20gU25vdydzIDE4NTYgIkNob2xlcmEgYW5kIHRoZSB3YXRlciBzdXBwbHkgLi4uIiB1c2luZyBhIGRpZmZlcmVuY2UtaW4tZGlmZmVyZW5jZXMgZnJhbWV3b3JrLiBUaGlzIG5vdGVib29rIGJ1aWxkcyBvbiB0aGUgaWRlYXMgaW4gdGhlIG5vdGVib29rICJTbm93MTg1Nl9UYWJsZVZJX0ludHJvIiBidXQgaXMgc3RhbmQtYWxvbmUgY2FuIGJlIHJ1biBzZXBhcmF0ZWx5LiAKCldpdGggcG9wdWxhdGlvbiBkYXRhIGJ5IHN1Yi1kaXN0cmljdCBhbmQgYnkgd2F0ZXIgc3VwcGx5IGNvbXBhbnkgKG9yaWdpbmFsbHkgcHVibGlzaGVkIGluIFNpbW9uIDE4NTYsICJSZXBvcnQgb24gdGhlIGxhc3QgdHdvIGNob2xlcmEtZXBpZGVtaWNzIG9mIExvbmRvbiIpLCBTbm93IHdhcyBhYmxlIHRvIGNvbXBhcmUgbW9ydGFsaXR5IGF0IHRoZSBzdWItZGlzdHJpY3QgbGV2ZWwgbW9yZSBjbG9zZWx5IHRoYW4gaGUgY291bGQgaW4gaGlzIDE4NTUgIk9uIHRoZSBtb2RlIG9mIGNvbW11bmljYXRpb24gLi4uIi4gSW4gVGFibGUgVkkgU25vdyB1c2VkIGVzdGltYXRlcyBvZiBtb3J0YWxpdHkgcmF0ZXMgZm9yIFNvdXRod2FyayAmIFZhdXhoYWxsIHZlcnN1cyBMYW1iZXRoLCBjb21iaW5lZCB3aXRoIHBvcHVsYXRpb24gZnJhY3Rpb25zIGJ5IHN1Yi1kaXN0cmljdCwgdG8gY2FsY3VsYXRlIHBvcHVsYXRpb24td2VpZ2h0ZWQgcHJlZGljdGVkIG1vcnRhbGl0eSBieSBzdWItZGlzdHJpY3QuIFNub3cncyBnb2FsIHdhcyB0byBzaG93IHRoYXQgZGlmZmVyZW5jZXMgaW4gd2F0ZXIgc3VwcGx5IHdhcyB0aGUgcHJlZG9taW5hbnQgZmFjdG9yIC0gbW9yZSBpbXBvcnRhbnQgdGhhbiBjcm93ZGluZyBvciBvdGhlciBmYWN0b3JzIC0gaW4gYWNjb3VudGluZyBmb3IgZGlmZmVyZW5jZXMgYWNyb3NzIHN1Yi1kaXN0cmljdHMuIAoKU25vdywgaG93ZXZlciwgZGlkIG5vdCBoYXZlIHRoZSBzdGF0aXN0aWNhbCB0b29scyBhbmQgbWV0aG9kb2xvZ3kgYXZhaWxhYmxlIHRvIHVzIHRvZGF5LCBhbmQgaGlzIGFyZ3VtZW50IGhhZCBuZWl0aGVyIHRoZSBjbGFyaXR5IG5vciB0aGUgcmlnb3Igd2Ugd291bGQgZGVtYW5kIHRvZGF5LiBUaGlzIG5vdGVib29rIHVzZXMgYSBtb3JlIGFwcHJvcHJpYXRlIHN0YXRpc3RpY2FsIGFwcHJvYWNoOiByZWdyZXNzaW9uIHRoYXQgdXNlcyB0aGUgcG9wdWxhdGlvbiBieSBzdWItZGlzdHJpY3QgYW5kIHdhdGVyIGNvbXBhbnkgdG8gc2ltdWx0YW5lb3VzbHkgZXN0aW1hdGUgYW5kIHRlc3QgZGlmZmVyZW5jZXMgYWNyb3NzIHRoZSB3YXRlciBjb21wYW5pZXMgKGFuZCBhY3Jvc3MgdGltZSkuIFRoZSBjb25jbHVzaW9uIChub3Qgc3VycHJpc2luZ2x5KSBvdmVyd2hlbG1pbmdseSBzdXBwb3J0cyBTbm93J3MgY29udGVudGlvbiB0aGF0IGRpcnR5IHZlcnN1cyBjbGVhbiB3YXRlciBpcyB0aGUgbW9zdCBpbXBvcnRhbnQgZmFjdG9yIGluIGFjY291bnRpbmcgZm9yIGRpZmZlcmVuY2VzIGFjcm9zcyBzdWItZGlzdHJpY3RzIChhbmQgYWNyb3NzIHRpbWUpLiBBcyBhIGRpZ3Jlc3Npb24gSSBleGFtaW5lIGVhcmxpZXIgZWZmb3J0cyBpbiB0aGUgbGl0ZXJhdHVyZSB0byBhZGRyZXNzIGFuZCBleHRlbmQgU25vdydzIFRhYmxlIFZJLCBkaXNjdXNzaW5nIHdoeSB0aG9zZSBlZmZvcnRzIGZhbGwgc2hvcnQuIAoKCkZvciBhIGJyaWVmIGludHJvZHVjdGlvbiB0byBTbm93J3Mgd29yaywgc2VlOgoKKyAqKlNub3cncyBvcmlnaW5hbCAxODU1IG1vbm9ncmFwaCoqIChpdCBpcyBtYXN0ZXJmdWwpOiBTbm93LCBKb2huLiAxODU1LiAqT24gdGhlIE1vZGUgb2YgQ29tbXVuaWNhdGlvbiBvZiBDaG9sZXJhKi4gMm5kIGVkLiBMb25kb246IEpvaG4gQ2h1cmNoaWxsLiBodHRwOi8vYXJjaGl2ZS5vcmcvZGV0YWlscy9iMjg5ODUyNjYuCisgKipUaGUgYmVzdCBwb3B1bGFyIGV4cG9zaXRpb24gSSBoYXZlIGZvdW5kKio6IEpvaG5zb24sIFN0ZXZlbi4gMjAwNy4gKlRoZSBHaG9zdCBNYXA6IFRoZSBTdG9yeSBvZiBMb25kb27igJlzIE1vc3QgVGVycmlmeWluZyBFcGlkZW1pYy0tYW5kIEhvdyBJdCBDaGFuZ2VkIFNjaWVuY2UsIENpdGllcywgYW5kIHRoZSBNb2Rlcm4gV29ybGQqLiBSZXByaW50IGVkaXRpb24uIE5ldyBZb3JrOiBSaXZlcmhlYWQgQm9va3MuCisgKipBbm90aGVyIGdvb2QgcG9wdWxhciB2ZXJzaW9uKio6IEhlbXBlbCwgU2FuZHJhLiAyMDA3LiAqVGhlIFN0cmFuZ2UgQ2FzZSBvZiB0aGUgQnJvYWQgU3RyZWV0IFB1bXA6IEpvaG4gU25vdyBhbmQgdGhlIE15c3Rlcnkgb2YgQ2hvbGVyYSouIEZpcnN0IGVkaXRpb24uIEJlcmtlbGV5OiBVbml2ZXJzaXR5IG9mIENhbGlmb3JuaWEgUHJlc3MuCisgKipUdWZ0ZSdzIGNsYXNzaWMgZGlzY3Vzc2lvbiBvZiBTbm93J3MgbWFwcGluZyoqIChhIHRvcGljIEkgZG9uJ3QgY292ZXIgaGVyZSk6IFR1ZnRlLCBFZHdhcmQgUi4gMTk5Ny4gKlZpc3VhbCBFeHBsYW5hdGlvbnM6IEltYWdlcyBhbmQgUXVhbnRpdGllcywgRXZpZGVuY2UgYW5kIE5hcnJhdGl2ZSouIDFzdCBlZGl0aW9uLiBHcmFwaGljcyBQcmVzcy4KKyAqKkJpb2dyYXBoeSoqOiBWaW50ZW4tSm9oYW5zZW4sIFBldGVyLCBIb3dhcmQgQnJvZHksIE5pZ2VsIFBhbmV0aCwgU3RlcGhlbiBSYWNobWFuLCBhbmQgTWljaGFlbCBSdXNzZWxsIFJpcC4gMjAwMy4gKkNob2xlcmEsIENobG9yb2Zvcm0gYW5kIHRoZSBTY2llbmNlIG9mIE1lZGljaW5lOiBBIExpZmUgb2YgSm9obiBTbm93Ki4gT3hmb3JkOyBOZXcgWW9yazogT3hmb3JkIFVuaXZlcnNpdHkgUHJlc3MuIExpbmtlZCBvbi1saW5lIHJlc291cmNlcyBodHRwczovL2pvaG5zbm93Lm1hdHJpeC5tc3UuZWR1L3Nub3d3b3Jrcy5waHAKCgoKClRoaXMgaXMgYW4gW1IgTWFya2Rvd25dKGh0dHA6Ly9ybWFya2Rvd24ucnN0dWRpby5jb20pIE5vdGVib29rLiBXaGVuIHlvdSBleGVjdXRlIGNvZGUgd2l0aGluIHRoZSBub3RlYm9vaywgdGhlIHJlc3VsdHMgYXBwZWFyIGJlbmVhdGggdGhlIGNvZGUuIFRoZSByZXN1bHRzIGFyZSBhbHNvIHNhdmVkIGluIGEgc2VsZi1jb250YWluZWQgaHRtbCBkb2N1bWVudCB3aXRoIHRoZSBzdWZmaXggKi5uYi5odG1sKi4gSWYgeW91IHdhbnQgcHVyZSByIGNvZGUgKGZvciBleGFtcGxlIHRvIHJ1biBvdXRzaWRlIFJTdHVkaW8pIHlvdSBjYW4gZWFzaWx5IGV4dHJhY3QgY29kZSB3aXRoIHRoZSBjb21tYW5kICprbml0KCdub3RlYm9vay5SbWQnLHRhbmdsZT1UUlVFKSogd2hpY2ggd2lsbCBzYXZlIGEgZmlsZSAnbm90ZWJvb2suUicgdW5kZXIgeW91ciB3b3JraW5nIGRpcmVjdG9yeS4KClRyeSBleGVjdXRpbmcgdGhlIGNodW5rIGJlbG93IGJ5IGNsaWNraW5nIHRoZSAqUnVuKiBidXR0b24gd2l0aGluIHRoZSBjaHVuayBvciBieSBwbGFjaW5nIHlvdXIgY3Vyc29yIGluc2lkZSBpdCBhbmQgcHJlc3NpbmcgKkNtZCtTaGlmdCtFbnRlciouIAoKYGBgYGBge3IgbWVzc2FnZT1GQUxTRSwgcmVzdWx0cz0naGlkZSd9CiMgQ29weXJpZ2h0IChjKSAyMDE5LCBUaG9tYXMgQ29sZW1hbgojCiMgIC0tLS0tLS0gIExpY2Vuc2VkIHVuZGVyIEJTRCAyLUNsYXVzZSAiU2ltcGxpZmllZCIgTGljZW5zZSAgLS0tLS0tLQojCiMgUmVzdWx0cyBhbmQgZGlzY3Vzc2lvbiBpbiAiQ2F1c2FsaXR5IGluIHRoZSBUaW1lIG9mIENob2xlcmE6IEpvaG4gU25vdyBhcyBhIFByb3RvdHlwZSAKIyBmb3IgQ2F1c2FsIEluZmVyZW5jZSAoV29ya2luZyBQYXBlcikiIGF2YWlsYWJsZSBhdCBTU1JOOiBodHRwczovL3BhcGVycy5zc3JuLmNvbS9hYnN0cmFjdD0zMjYyMjM0CgpybShsaXN0PWxzKCkpICAgICMgc3RhcnRzIGEgZnJlc2ggd29ya3NwYWNlCiMKbGlicmFyeShrbml0cikKb3B0aW9ucyhzY2lwZW49NSkKIyBUaGUgZm9sbG93aW5nIGxpYnJhcmllcyBhcmUgdXNlZCBmb3IgdGhlIE5lZ2F0aXZlIEJpbm9taWFsIHJlZ3Jlc3Npb24gYW5kIHRoZSByb2J1c3Qgc3RhbmRhcmQgZXJyb3IgYW5hbHlzaXMKI2luc3RhbGwucGFja2FnZXMoInNhbmR3aWNoIikKI2luc3RhbGwucGFja2FnZXMoImxtdGVzdCIpCmxpYnJhcnkoIk1BU1MiKQpsaWJyYXJ5KCJzYW5kd2ljaCIpIApsaWJyYXJ5KCJsbXRlc3QiKSAKCiMgUmVhZCBpbiBwbG90IGZ1bmN0aW9ucyAtIHNlZSB0aGUgUiBjb2RlIG9yIHRoZSBub3RlYm9vayAnU25vdzE4NTVfRGlEUmVncmVzc2lvbjJfRXJyb3JBbmFseXNpcy5ybWQnIGZvciBhIGRlc2NyaXB0aW9uIG9mIHRob3NlIGZ1bmN0aW9uCnNvdXJjZSgnU25vd1Bsb3RGbnMucicpIAoKIyBSZWFkIGluIHRoZSBkYXRhIGZyb20gU25vdyAxODU1ICJPbiB0aGUgbW9kZSBvZiBjb21tdW5pY2F0aW9uIG9mIGNob2xlcmEiCnRhYmxldmlpaSA8LSByZWFkLmNzdihmaWxlPSJTbm93MTg1NV9UYWJsZVZJSUkuY3N2IiwgaGVhZGVyPVRSVUUsIHNlcD0iLCIsIHNraXA9NSxjb21tZW50LmNoYXI9IiMiKQp0YWJsZXhpaSA8LSByZWFkLmNzdihmaWxlPSJTbm93MTg1NV9UYWJsZVhJSS5jc3YiLCBoZWFkZXI9VFJVRSwgc2VwPSIsIiwgc2tpcD01LGNvbW1lbnQuY2hhcj0iIyIpCgojIFJlYWQgaW4gdGhlIGRhdGEgZnJvbSBKb2huIFNub3cgMTg1NiwgIkNob2xlcmEgYW5kIHRoZSB3YXRlciBzdXBwbHkgaW4gdGhlIHNvdXRoIGRpc3RyaWN0IG9mIExvbmRvbiBpbiAxODU0IiwgCiMgICBUaGVzZSBkYXRhIHdlcmUgY29waWVkIGZyb20gdGhlIDE5MzYgYm9vayAiU25vdyBvbiBjaG9sZXJhLCBiZWluZyBhIHJlcHJpbnQgb2YgdHdvIHBhcGVycyIgZWRpdGVkIGJ5IEZyb3N0CiMgVGFibGUgViBieSBEaXN0cmljdCAoZm9yIHJ1bm5pbmcgUG9pc3NvbiAmIE5lZyBCaW5vbWlhbCBjb3VudCByZWdyZXNzaW9ucykKIyBUYWJsZSBWSSBieSBzdWItZGlzdHJpY3QgKGZvciBydW5uaW5nIEtvY2ggJiBEZW5pa2UncyB0ZXN0cykKCiMgVGFibGUgSSAiU2hvd2luZyB0aGUgcmVzdWx0cyBvZiB0aGUgQXV0aG9yJ3MgcGVyc29uYWwgSW5xdWlyeSBpbnRvIFR3ZW50eS1PbmUgU3ViLURpc3RyaWN0cyIKIyBUYWJsZSBJSSAiU2hvd2luZyB0aGUgcmVzdWx0cyBvZiBJbnF1aXJ5IG1hZGUgYnkgTXIuIFdoaXRpbmcgaW4gRWxldmVuIFN1Yi1EaXN0cmljdHMiCiMgKE15ICJ0YWJsZWlfMTg1NiIgY29tYmluZXMgU25vdydzIFRhYmxlcyBJICYgSUkpCgp0YWJsZWlfMTg1NiA8LSByZWFkLmNzdihmaWxlPSJTbm93MTg1Nl9UYWJsZUkuY3N2IiwKICBoZWFkZXI9VFJVRSwgc2VwPSIsIiwgc2tpcD01LGNvbW1lbnQuY2hhcj0iIyIpCgp0YWJsZVZfMTg1NiA8LSByZWFkLmNzdihmaWxlPSJTbm93MTg1Nl9UYWJsZVYuY3N2IiwKICBoZWFkZXI9VFJVRSwgc2VwPSIsIiwgc2tpcD01LGNvbW1lbnQuY2hhcj0iIyIpCnRhYmxlVklfMTg1NiA8LSByZWFkLmNzdihmaWxlPSJTbm93MTg1Nl9UYWJsZVZJLmNzdiIsCiAgaGVhZGVyPVRSVUUsIHNlcD0iLCIsIHNraXA9NSxjb21tZW50LmNoYXI9IiMiKQoKCmBgYAoKCiMjI0RpZmZlcmVuY2UtaW4tRGlmZmVyZW5jZXMgUmVncmVzc2lvbiB3aXRoIFBvcHVsYXRpb24gV2VpZ2h0cwoKIyMjI1NldHRpbmcgdGhlIFNjZW5lCgpJbiBTbm93IDE4NTYgd2UgaGF2ZSBlc3RpbWF0ZWQgaG91c2VzIGFuZCBlc3RpbWF0ZWQgcG9wdWxhdGlvbiBhc3NpZ25lZCB0byB0aGUgdHdvIHdhdGVyIHN1cHBseSBjb21wYW5pZXMuIEJ1dCB0aGVyZSBhcmUgYWN0dWFsbHkgKnRocmVlKiBzb3VyY2VzIG9mIHdhdGVyOiBTb3V0aHdhcmsgJiBWYXV4aGFsbCBDbywgTGFtYmV0aCBDbywgYW5kICJPdGhlciIgKHB1bXAtd2VsbHMsIFRoYW1lcywgZGl0Y2hlcykuIFRoZXJlIGlzIGNvbnNpZGVyYWJsZSB2YXJpYXRpb24gYWNyb3NzIHN1Yi1kaXN0cmljdHMgbm90IG9ubHkgaW4gdGhlIHByb3BvcnRpb24gc3VwcGxpZWQgYnkgU291dGh3YXJrIHZlcnN1cyBMYW1iZXRoLCBidXQgYWxzbyBpbiB0aGUgdG90YWwgcHJvcG9ydGlvbiBzdXBwbGllZCBieSB3YXRlciBjb21wYW5pZXMgdmVyc3VzICJvdGhlciIuIAoKCmBgYHtyfQp0YWJsZWlfMTg1NiRjb21iaW5lZF9wb3AgPC0gdGFibGVpXzE4NTYkc291dGh3YXJrX3BvcCArIHRhYmxlaV8xODU2JGxhbWJldGhfcG9wCnRhYmxlaV8xODU2W2MoInN1YkRpc3RyaWN0IiwicG9wMTg1MSIsInNvdXRod2Fya19wb3AiLCJsYW1iZXRoX3BvcCIsImNvbWJpbmVkX3BvcCIpXQpgYGAKClRoZSBlc3RpbWF0ZXMgcHVibGlzaGVkIGluIFNub3cgMTg1NiBUYWJsZXMgSSBhbmQgSUkgKGRpc3BsYXllZCBhYm92ZSkgc2hvdyB0aGF0IGZvciBTdC4gU2F2aW91ciwgU291dGh3YXJrIGByIHJvdW5kKDEwMCAqIHRhYmxlaV8xODU2JHNvdXRod2Fya19wb3BbMV0gLyB0YWJsZWlfMTg1NiRwb3AxODUxWzFdLDEpYCUgd2FzIHN1cHBsaWVkIGJ5IHRoZSBTb3V0aHdhcmsgd2F0ZXIgY29tcGFueSwgYHIgcm91bmQoMTAwICogdGFibGVpXzE4NTYkbGFtYmV0aF9wb3BbMV0gLyB0YWJsZWlfMTg1NiRwb3AxODUxWzFdLDEpYCUgYnkgTGFtYmV0aCwgYW5kIGByIHJvdW5kKDEwMCAqIHRhYmxlaV8xODU2JGNvbWJpbmVkX3BvcFsxXSAvIHRhYmxlaV8xODU2JHBvcDE4NTFbMV0sMSlgJSBieSB0aGUgdHdvIGNvbWJpbmVkLiBGb3IgU3QuIE1hcnksIE5ld2luZ3RvbiBgciByb3VuZCgxMDAgKiB0YWJsZWlfMTg1NiRzb3V0aHdhcmtfcG9wWzE5XSAvIHRhYmxlaV8xODU2JHBvcDE4NTFbMTldLDEpYCUgd2FzIHN1cHBsaWVkIGJ5IHRoZSBTb3V0aHdhcmsgQ29tcGFueSwgYHIgcm91bmQoMTAwICogdGFibGVpXzE4NTYkbGFtYmV0aF9wb3BbMTldIC8gdGFibGVpXzE4NTYkcG9wMTg1MVsxOV0sMSlgJSBieSBMYW1iZXRoLCBhbmQgb25seSBgciByb3VuZCgxMDAgKiB0YWJsZWlfMTg1NiRjb21iaW5lZF9wb3BbMTldIC8gdGFibGVpXzE4NTYkcG9wMTg1MVsxOV0sMSlgJSBieSB0aGUgdHdvIGNvbWJpbmVkLiAKCk5vdGUgaW4gcGFzc2luZyB0aGF0IHRoZXJlIGFyZSBwcm9ibGVtcyB3aXRoIHRoZSBwb3B1bGF0aW9uIGVzdGltYXRlcyAod2hpY2ggU25vdyBoaWdobGlnaHRlZCkuIFNvbWUgc3ViLWRpc3RyaWN0cyB0aGF0IHdlcmUgaW4gZmFjdCBub3Qgc3VwcGxpZWQgYnkgdGhlIExhbWJldGggQ29tcGFueSAoc3VjaCBhcyBTdC4gU2F2aW91ciwgU291dGh3YXJrKSBoYXZlIGluY29ycmVjdGx5LXJlcG9ydGVkIExhbWJldGggcG9wdWxhdGlvbi4gU29tZSBzdWItZGlzdHJpY3RzIChzdWNoIGFzIFN0LiBNYXJ5IE1hZ2RhbGVuKSBoYXZlIGEgbGFyZ2VyIGNvbWJpbmUgU291dGh3YXJrICsgTGFtYmV0aCBwb3B1bGF0aW9uIHRoYW4gdGhlIDE4NTEgY2Vuc3VzIHBvcHVsYXRpb24uCgpUbyBhY2NvdW50IGZvciB0aGUgdmFyaWF0aW9uIGluIG9ic2VydmVkIHN1Yi1kaXN0cmljdCBtb3J0YWxpdHkgd2UgbmVlZCB0byBtZWFzdXJlIHRoZSBwb3B1bGF0aW9uIGRpZmZlcmVuY2VzIGZvciBhbGwgdGhyZWUgc291cmNlczsgU25vdyBpbiBUYWJsZSBWSSBvbmx5IGFjY291bnRlZCBmb3IgdGhlIGZpcnN0IHR3by4gVG8gZG8gdGhpcyB3ZSBjYW4gbW9kZWwgdGhlIG1vcnRhbGl0eSByYXRlIGZvciBhIHN1Yi1kaXN0cmljdCBhcyB0aGUgcG9wdWxhdGlvbi13ZWlnaHRlZCBhdmVyYWdlOgoKJFJfe3N1YmRpcyx5cn0gPSBSX1MgKiBQX1MgKyBSX0xeezU0fSAqIFBfTCAqIElfe3lyPTE4NTR9ICsgUl9MICogUF9MICsgUl9PICogUF9PICsgXGRlbHRhX3s1NH0gKiBJX3t5cj0xODU0fSArIFxlcHNpbG9uJAoKKyAkUl9TIC4uLiQgPSAoZXN0aW1hdGVkKSBtb3J0YWxpdHkgcmF0ZSBmb3IgU291dGh3YXJrLCBMYW1iZXRoLCBPdGhlcgorICRQX1MgLi4uJCA9IChvYnNlcnZlZCkgcG9wdWxhdGlvbiBwcm9wb3J0aW9uIGZvciBTb3V0aHdhcmssIExhbWJldGgsIE90aGVyCisgJFJfTF57NTR9JCA9IChlc3RpbWF0ZWQpIExhbWJldGggMTg1NCBlZmZlY3QgKGNsZWFuIHdhdGVyIHRyZWF0bWVudCBlZmZlY3QpCgpUbyBoaWdobGlnaHQgYW5kIG1vcmUgZWFzaWx5IHRlc3QgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBTb3V0aHdhcmsgYW5kIExhbWJldGggd2UgY2FuIG5vdGUgdGhhdCAkUF9TID0gMSAtIFBfTCAtIFBfTyQsIHVzZSAkUl9TJCBhcyB0aGUgb3ZlcmFsbCBjb25zdGFudCwgYW5kIHdyaXRlCgokUl97c3ViZGlzLHlyfSA9IFJfUyArIChSX0xeezU0fS1SX1MpICogUF9MICogSV97eXI9MTg1NH0gKyAoUl9MLVJfUykgKiBQX0wgKyAoUl9PLVJfUykgKiBQX08gKyBcZGVsdGFfezU0fSAqIElfe3lyPTE4NTR9ICsgXGVwc2lsb24kCgpzbyB0aGF0IHRoZSBlc3RpbWF0ZWQgY29lZmZpY2llbnRzICgkKFJfTC1SX1MpJCkgYXJlIHRoZSBkaWZmZXJlbmNlIGZyb20gdGhlIGV4Y2x1ZGVkIChTb3V0aHdhcmspIGNhdGVnb3J5LiAKCiMjIyNDcmVhdGluZyB0aGUgRGF0YQoKSnVzdCBhcyBmb3IgdGhlIG5vdGVib29rICJTbm93MTg1NV9EaURSZWdyZXNzaW9uMSIgd2UgbXVzdCBzdGFjayB0aGUgZGF0YSBmcm9tIFNub3cgMTg1NSBUYWJsZXMgVklJSSBhbmQgWElJIGFuZCBjcmVhdGUgYXBwcm9wcmlhdGUgaW5kaWNhdG9yIHZhcmlhYmxlcy4gSGVyZSB3ZSBhbHNvIG5lZWQgdG8gbWVyZ2UgaW4gdGhlIHBvcHVsYXRpb24gZXN0aW1hdGVzIGZyb20gU25vdyAxODU2IFRhYmxlcyBJICYgSUkuCgpgYGB7cn0KeDEgPC0gc3Vic2V0KHRhYmxldmlpaSxzdXBwbGllciA9PSAiU291dGh3YXJrVmF1eGhhbGwiIHwgc3VwcGxpZXIgPT0gIlNvdXRod2Fya1ZhdXhoYWxsX0xhbWJldGgiKQp4MTg0OSA8LSB4MVtjKCJzdWJEaXN0cmljdCIsInBvcDE4NTEiLCJzdXBwbGllciIsImxhbWJldGhkZWdyZWUiKV0KeDEgPC0gc3Vic2V0KHRhYmxleGlpLHN1cHBsaWVyID09ICJTb3V0aHdhcmtWYXV4aGFsbCIgfCBzdXBwbGllciA9PSAiU291dGh3YXJrVmF1eGhhbGxfTGFtYmV0aCIpCngxODQ5JGRlYXRocyA8LSB4MSRkZWF0aHMxODQ5CngxODQ5JHJhdGUgPC0gMTAwMDAgKiB4MSRkZWF0aHMxODQ5IC8geDE4NDkkcG9wMTg1MQp4MTg0OSRzZXEgPC0gYyhzZXEoMSxsZW5ndGgoeDE4NDkkZGVhdGhzKSkpCiN4MTg0OSRkdW0xODU0IDwtIDAKeHllYXIgPC0gZmFjdG9yKGMocmVwKDE4NDksMjgpLHJlcCgxODU0LDI4KSkpCngxODQ5JHllYXIgPC0geHllYXJbMToyOF0KeDE4NTQgPC0geDE4NDkKI3gxODQ5JGxhbWJldGhkZWdyZWUgPC0gImRpcnR5Igp4MTg1NCRkZWF0aHMgPC0geDEkZGVhdGhzMTg1NAp4MTg1NCRyYXRlIDwtIDEwMDAwICogeDEkZGVhdGhzMTg1NCAvIHgxODQ5JHBvcDE4NTEKeDE4NTQkc2VxIDwtIGMoc2VxKDEsbGVuZ3RoKHgxODQ5JGRlYXRocykpKQojeDE4NTQkZHVtMTg1NCA8LSAxCngxODU0JHllYXIgPC0geHllYXJbMjk6NTZdCgoKIyBGaXJzdCwgcmUtZ2VuZXJhdGUgInJlZGdhdGEiIGFmdGVyIHBhc3Rpbmcgb24gcG9wdWxhdGlvbiBmcmFjdGlvbnMuIAojIEZvciAxODQ5IGFuZCBmb3IgU291dGh3YXJrLW9ubHkgc3ViLWRpc3RyaWN0cyAKCiMgTGFtYmV0aCBwb3B1bGF0aW9uIGFzIHBlcmNlbnQgb2YgdG90YWwgKDE4NTEpIHBvcHVsYXRpb24uIFplcm8gb3V0IHRoZSBub24tTGFtYmV0aCBzdWItZGlzdHJpY3RzICgiZmlyc3QgMTIiKQojIEkgd2FudCB0aHJlZSB2YXJpYWJsZXM6CiMgIDEpIExhbWJldGggZm9yIGJvdGggMTg0OSAmIDE4NTQgCiMgIDIpIE90aGVyIGZvciBib3RoIDE4NDkgJiAxODU0CiMgdGhlc2UgdHdvIHdpbGwgbWVhc3VyZSBhZ2FpbnN0IFNvdXRod2FyayBmb3IgZGlydHkgd2F0ZXIKIyAgMykgTGFtYmV0aCBmb3IgMTg1NCAgIC0gIHRoaXMgc2hvdWxkIG1lYXN1cmUgTGFtYmV0aCBmb3IgY2xlYW4gd2F0ZXIKeDE4NDkkb3RoZXJwZXJjIDwtIDAKeDE4NTQkb3RoZXJwZXJjIDwtIDAKeDE4NDkkbGFtYmV0aHBlcmMgPC0gMAp4MTg1NCRsYW1iZXRocGVyYyA8LSAwCngxODQ5JGxhbWJldGhwZXJjNTQgPC0gMAp4MTg1NCRsYW1iZXRocGVyYzU0IDwtIDAKIyBUaGlzIGNhbGN1bGF0ZXMgbGFtYmV0aCBhcyBwZXJjZW50IG9mIFRPVEFMIHBvcHVsYXRpb24uIEkgdGhpbmsgdGhpcyBpcyByaWdodCBmb3IKIyBtZWFzdXJpbmcgdGhlICJMYW1iZXRoIGVmZmVjdCIgYmVjYXVzZSBpdCBnaXZlcyB0aGUgcHJvcG9ydGlvbiBvZiB0aGUgcG9wdWxhdGlvbiB0cmVhdGVkICh3aXRoIGNsZWFuIExhbWJldGggd2F0ZXIpCiMgd2hpY2ggaXMgdGhlIHZhcmlhdGlvbiBmcm9tIDE4NDkgdG8gMTg1NAp4MTg0OSRvdGhlcnBlcmMgPC0gMSAtICh0YWJsZWlfMTg1NlsxOjI4LF0kc291dGh3YXJrX3BvcCArIHRhYmxlaV8xODU2WzE6MjgsXSRsYW1iZXRoX3BvcCApIC8KCXRhYmxlaV8xODU2WzE6MjgsXSRwb3AxODUxCngxODU0JG90aGVycGVyYyA8LSB4MTg0OSRvdGhlcnBlcmMKIyBWYXJpYWJsZSBmb3Igb25seSAxOTU0IExhbWJldGgKeDE4NTRbMTM6MjgsXSRsYW1iZXRocGVyYzU0IDwtIHRhYmxlaV8xODU2WzEzOjI4LF0kbGFtYmV0aF9wb3AgLyB0YWJsZWlfMTg1NlsxMzoyOCxdJHBvcDE4NTEKeDE4NDkkbGFtYmV0aHBlcmMgPC0geDE4NTQkbGFtYmV0aHBlcmM1NAp4MTg1NCRsYW1iZXRocGVyYyA8LSB4MTg0OSRsYW1iZXRocGVyYwoKIyBwb3B1bGF0aW9uIHBlciBob3VzZSBzZWVtcyB0byBjb21lIGluIGFzIGZhY3RvciAtIGNvbnZlcnQgdG8gbnVtZXJpYwp4MTg0OSRwb3BfcGVyX2hvdXNlIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHRhYmxlaV8xODU2JHBvcF9wZXJfaG91c2VbMToyOF0pKQp4MTg1NCRwb3BfcGVyX2hvdXNlIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHRhYmxlaV8xODU2JHBvcF9wZXJfaG91c2VbMToyOF0pKQoKcmVnZGF0YSA8LSByYmluZCh4MTg0OSx4MTg1NCkKCnJlZ2RhdGEKYGBgCgojIyMjT0xTIExpbmVhciBSZWdyZXNzaW9ucwoKV2l0aCB0aGUgZGF0YWZyYW1lICJyZWdkYXRhIiB3ZSBjYW4gbm93IHJ1biB2YXJpb3VzIHJlZ3Jlc3Npb25zLiBUbyBzdGFydCBqdXN0IHRoZSBzaW1wbGUgT0xTIGxpbmVhciByZWdyZXNzaW9uLgoKYGBge3J9CiMgTGluZWFyIHdpdGggbm8gcG9wdWxhdGlvbiBkZW5zaXR5CmxpbnByb3BuIDwtIGxtKHJhdGUgfiBsYW1iZXRocGVyYzU0ICsgbGFtYmV0aHBlcmMgKyBvdGhlcnBlcmMgKyB5ZWFyLCBkYXRhPXJlZ2RhdGEgKQpsaW5wcm9wbnJvYnVzdHNlIDwtIGNvZWZ0ZXN0KGxpbnByb3BuLCB2Y292ID0gdmNvdkhDKGxpbnByb3BuKSkKc3VtbWFyeShsaW5wcm9wbikKCmBgYAoKVGhlICJMYW1iZXRoIiBvciBjbGVhbiB3YXRlciBlZmZlY3QgaXMgdGhlIGNvZWZmaWNpZW50ICJgciBsYWJlbHMobGlucHJvcG4kY29lZmZpY2llbnRzWzJdKWAiID0gYHIgcm91bmQoc3VtbWFyeShsaW5wcm9wbikkY29lZmZpY2llbnRzWzIsMV0sMSlgIC0gdGhlIG1vcnRhbGl0eSBwZXIgMTAsMDAwIGZvciBMYW1iZXRoIGNvbXBhbnkgY3VzdG9tZXJzLCBhcyBhIGRpZmZlcmVuY2UgZnJvbSBTb3V0aHdhcmsgJiBWYXV4aGFsbCBjb21wYW55IGN1c3RvbWVycy4gVGhlIHogdmFsdWUgb2YgYHIgcm91bmQoc3VtbWFyeShsaW5wcm9wbikkY29lZmZpY2llbnRzWzIsM10sMSlgIGluZGljYXRlcyB0aGF0IHRoaXMgaXMgc3RhdGlzdGljYWxseSBzaWduaWZpY2FudC4gVGhlIHZhbHVlIGl0c2VsZiBpcyB2ZXJ5IGxhcmdlLCB0ZWxsaW5nIHVzIHRoYXQgaW4gMTg1NCB0aGUgbW9ydGFsaXR5IHJhdGUgb2YgTGFtYmV0aCBjdXN0b21lcnMgd2FzIGByIHJvdW5kKHN1bW1hcnkobGlucHJvcG4pJGNvZWZmaWNpZW50c1syLDFdLDApYCBwZXIgMTAsMDAwIGxvd2VyIHRoYW4gZm9yIFNvdXRod2FyayAmIFZhdXhoYWxsIGN1c3RvbWVycyAtIGEgKnZlcnkqIGxhcmdlIGRpZmZlcmVuY2UgZ2l2ZW4gdGhhdCB0aGUgYmFzZSBTb3V0aHdhcmsgJiBWYXV4aGFsbCBtb3J0YWxpdHkgd2FzIGByIHJvdW5kKHN1bW1hcnkobGlucHJvcG4pJGNvZWZmaWNpZW50c1sxLDFdLDApYC4KClRoZSBhZGp1c3RlZCBSLXNxdWFyZWQgdGVzdHMgd2hldGhlciB2YXJpYXRpb25zIGluIHRoZSBwb3B1bGF0aW9uIHByb3BvcnRpb25zIGFuZCBkaWZmZXJlbmNlcyBpbiB3YXRlciBzdXBwbHkgYWNjb3VudCBmb3IgbXVjaCBvZiB0aGUgb2JzZXJ2ZWQgdmFyaWF0aW9uIGluIG1vcnRhbGl0eSwgZXhhY3RseSB3aGF0IFNub3cgd2FzIHRyeWluZyB0byB0ZXN0LiBUaGUgaGlnaCBSLXNxdWFyZWQgc2hvd3MgdGhhdCBpbmRlZWQgZGlmZmVyZW5jZXMgaW4gbW9ydGFsaXR5IGJldHdlZW4gd2F0ZXIgc3VwcGxpZXJzIGFjY291bnRzIGZvciBtdWNoIG9mIHRoZSBvYnNlcnZlZCB2YXJpYXRpb24uIAoKVGhlIHBvcHVsYXRpb24gZXN0aW1hdGVzIHB1Ymxpc2hlZCBpbiAxODU2IGFsc28gaW5jbHVkZWQgaG91c2luZyBkZW5zaXR5IGVzdGltYXRlcy4gT25lIHBvcHVsYXIgYW5kIHZlcnkgcmVhc29uYWJsZSBoeXBvdGhlc2lzIHdhcyB0aGF0IGNyb3dkaW5nIGxlZCB0byBoaWdoZXIgY2hvbGVyYSBtb3J0YWxpdHkuIFdlIGNhbiB0ZXN0IHRoZSBlZmZlY3Qgb2YgZGlmZmVyZW5jZXMgaW4gY3Jvd2RpbmcsIHdpdGhpbiB0aGlzIHJlZ2lvbiBvZiBzb3V0aCBMb25kb24sIGJ5IGluY2x1ZGluZyBob3VzaW5nIGRlbnNpdHkgYXMgYSByZWdyZXNzb3IuIAoKYGBge3J9CiMgTGluZWFyIHdpdGggcG9wdWxhdGlvbiBkZW5zaXR5CmxpbnByb3BuX2RlbiA8LSBsbShyYXRlIH4gbGFtYmV0aHBlcmM1NCArIGxhbWJldGhwZXJjICsgb3RoZXJwZXJjICsgeWVhcgoJKyBwb3BfcGVyX2hvdXNlICwgZGF0YT1yZWdkYXRhKQpsaW5wcm9wbl9kZW5yb2J1c3RzZSA8LSBjb2VmdGVzdChsaW5wcm9wbl9kZW4sIHZjb3YgPSB2Y292SEMobGlucHJvcG5fZGVuKSkKc3VtbWFyeShsaW5wcm9wbl9kZW4pCgpgYGAKCgpEb2luZyBzbyBoYXMgdmlydHVhbGx5IGVmZmVjdCBvbiB0aGUgTGFtYmV0aCBjb2VmZmljaWVudCAtIGl0IGlzIHN0aWxsIGByIHJvdW5kKHN1bW1hcnkobGlucHJvcG5fZGVuKSRjb2VmZmljaWVudHNbMiwxXSwxKWAuIEhvdXNpbmcgZGVuc2l0eSBpcyBtYXJnaW5hbGx5IHNpZ25pZmljYW50IGJ1dCBhZGRzIGxpdHRsZSB0byB0aGUgb3ZlcmFsbCBleHBsYW5hdG9yeSBwb3dlciBvZiB0aGUgcmVncmVzc2lvbiAtIHRoZSBBZGp1c3RlZCBSLVNxdWFyZWQgaW5jcmVhc2VzIGZyb20gYHIgcm91bmQoc3VtbWFyeShsaW5wcm9wbikkYWRqLnIuc3F1YXJlZCwzKWAgdG8gYHIgcm91bmQoc3VtbWFyeShsaW5wcm9wbl9kZW4pJGFkai5yLnNxdWFyZWQsMylgLgoKV2UgY2FuIGFsc28gaW5jbHVkZSBmaXhlZCBlZmZlY3RzIGZvciBlYWNoIHN1Yi1kaXN0cmljdC4gSW5jbHVkaW5nIGhvdXNpbmcgZGVuc2l0eSBhc2tzICJkb2VzIHRoZSBkaWZmZXJlbmNlIGluIGRlbnNpdHkgYWNyb3NzIHN1Yi1kaXN0cmljdHMgaGVscCBleHBsYWluIG1vcnRhbGl0eSwgb3IgcmVkdWNlIHRoZSBpbXBvcnRhbmNlIG9mIGNsZWFuIHdhdGVyIGZvciBMYW1iZXRoIGN1c3RvbWVycz8iIEluY2x1ZGluZyBmaXhlZCBlZmZlY3RzIGFza3MgYSBkcmFtYXRpY2FsbHkgbW9yZSBnZW5lcmFsIHF1ZXN0aW9uOiAiYXJlIHRoZXJlIGFueSBkaWZmZXJlbmNlcyBhY3Jvc3Mgc3ViLWRpc3RyaWN0cyB0aGF0IGhlbHAgZXhwbGFpbiBtb3J0YWxpdHkgb3IgcmVkdWNlIHRoZSBpbXBvcnRhbmNlIG9mIGNsZWFuIHdhdGVyPyIgVGhlIGFuc3dlciBpcyBiYXNpY2FsbHkgIk5vIi4gCgpgYGB7cn0KIyBMaW5lYXIgd2l0aCBmaXhlZCBlZmZlY3RzCmxpbnByb3BuX0ZFIDwtIGxtKHJhdGUgfiBsYW1iZXRocGVyYzU0ICsgbGFtYmV0aHBlcmMgKyBvdGhlcnBlcmMgKyB5ZWFyCgkrIHN1YkRpc3RyaWN0LCBkYXRhPXJlZ2RhdGEgKQpsaW5wcm9wbl9GRXJvYnVzdHNlIDwtIGNvZWZ0ZXN0KGxpbnByb3BuX0ZFLCB2Y292ID0gdmNvdkhDKGxpbnByb3BuX0ZFKSkKc3VtbWFyeShsaW5wcm9wbl9GRSkKCmBgYAoKVGhlIEFkanVzdGVkIFItU3F1YXJlZCBpbmNyZWFzZXMgZnJvbSBgciByb3VuZChzdW1tYXJ5KGxpbnByb3BuKSRhZGouci5zcXVhcmVkLDMpYCB0byBgciByb3VuZChzdW1tYXJ5KGxpbnByb3BuX0ZFKSRhZGouci5zcXVhcmVkLDMpYCwgYnV0IHRoZSB2YWx1ZSBvZiB0aGUgTGFtYmV0aCBlZmZlY3QgaXMgdW5jaGFuZ2VkIGFuZCBpbiBmYWN0IGlzIG5vdyBlc3RpbWF0ZWQgZXZlbiBtb3JlIHByZWNpc2VseTogdCB2YWx1ZSBgciByb3VuZChzdW1tYXJ5KGxpbnByb3BuX0ZFKSRjb2VmZmljaWVudHNbMiwzXSwxKWAuIFllcyB0aGVyZSBhcmUgZGlmZmVyZW5jZXMgaW4gbW9ydGFsaXR5IGFjcm9zcyBzdWItZGlzdHJpY3RzIHRoYXQgYXJlIG5vdCBleHBsYWluZWQgb25seSBieSBkaWZmZXJlbmNlcyBpbiB3YXRlciBzdXBwbGllciwgYnV0IHdhdGVyIHN1cHBseSBzdGlsbCBoYXMgYSBkcmFtYXRpY2FsbHkgbGFyZ2UgYW5kIHByZWNpc2VseS1lc3RpbWF0ZWQgZWZmZWN0LiAKCiMjIyNDb3VudCAtIExpbmVhciBSZWdyZXNzaW9ucyAoUG9pc3NvbiAmIE5lZ2F0aXZlIEJpbm9taWFsIFJlZ3Jlc3Npb25zKQoKVGhlIE9MUyByZWdyZXNzaW9uIGFib3ZlIGlzIG5vdCByZWFsbHkgYXBwcm9wcmlhdGUgYmVjYXVzZSBvYnNlcnZlZCB2YXJpYWJsZXMgYXJlIGNvdW50cyAtIHBvc2l0aXZlIGFuZCBpbnRlZ2VyLXZhbHVlZCByYXRoZXIgdGhhbiB0aGUgY29udGludW91cyByYXRlcyB1c2VkIGluIHRoZSBhYm92ZSByZWdlc3Npb25zLiBGb3IgdGhlIG9ic2VydmVkIGNvdW50cyB0aGUgcmVncmVzc2lvbiByZXNpZHVhbHMgY2Fubm90IGJlIGNvbnRpbnVvdXMgbm9ybWFsIHZhcmlhYmxlcy4gV2UgbmVlZCB0byB0dXJuIHRvIFBvaXNzb24gb3IgTmVnYXRpdmUgQmlub21pYWwgcmVncmVzc2lvbi4gCgpUaGUgZGVmYXVsdCBmb3IgY291bnRzIChQb2lzc29uIGFuZCBOZWdhdGl2ZSBCaW5vbWlhbCByZWdyZXNzaW9ucykgaXMgdG8gZXN0aW1hdGUgaW4gbG9nIGZvcm0sIGFzIGRpc2N1c3NlZCBiZWxvdy4gSGVyZSwgaG93ZXJ2ZXIsIHdlIHdpbGwgdXNlIGEgbGluZWFyIHJlbGF0aW9uIGJldHdlZW4gdGhlIHJhdGVzIGFuZCByZWdyZXNzb3JzOgoKJFJfe3N1YmRpcyx5cn0gPSBSX1MgKyAoUl9MXns1NH0tUl9TKSAqIFBfTCAqIElfe3lyPTE4NTR9ICsgKFJfTC1SX1MpICogUF9MICsgKFJfTy1SX1MpICogUF9PICsgXGRlbHRhX3s1NH0gKiBJX3t5cj0xODU0fSQKClRoZSByYXRlIGlzIHRoZSBjb3VudCBkaXZpZGVkIGJ5IHRoZSBwb3B1bGF0aW9uOgoKJFJfe3N1YmRpcyx5cn0gPSBDb3VudF97c3ViZGlzLHlyfSAvIFBvcF97c3ViZGlzLHlyfSQKClRvIHRyYW5zZm9ybSBmcm9tIHRoZSByYXRlIGVxdWF0aW9uIHRvIGNvdW50cyB3ZSBuZWVkIHRvIG11bHRpcGx5IGFsbCB0aGUgcmVncmVzc29ycyBieSB0aGUgcG9wdWxhdGlvbjoKCiRDb3VudF97c3ViZGlzLHlyfSA9IFJfUypQb3Bfe3N1YmRpcyx5cn0gKyAoUl9MXns1NH0tUl9TKSAqIFx0aWxkZXtQfV9MICogSV97eXI9MTg1NH0gKyAoUl9MLVJfUykgKiBcdGlsZGV7UH1fTCArIChSX08tUl9TKSAqIFx0aWxkZXtQfV9PICsgXGRlbHRhX3s1NH0gKiBcdGlsZGV7SX1fe3lyPTE4NTR9ICsgXGVwc2lsb24kCgp3aGVyZSBJIGFtIHVzaW5nICRcdGlsZGV7UF9MfSAuLi4kIHRvIG1lYW4gJFBfTCAqIFBvcF97c3ViZGlzLHlyfSQuIChUaGlzIGFsc28gbWVhbnMgcnVubmluZyB0aGUgcmVncmVzc2lvbiB3aXRoIG5vIGludGVyY2VwdCBhbmQgdXNpbmcgJFBvcF97c3ViZGlzLHlyfSQgYXMgYSByZWdyZXNzb3IuKQoKVGhlIGZvbGxvd2luZyBjb2RlIGNodW5rIHJ1bnMgYSBQb2lzc29uIGFuZCBOZWdhdGl2ZSBCaW5vbWlhbCByZWdyZXNzaW9uIGJ1dCBkaXNwbGF5cyBvbmx5IHRoZSBOZWdhdGl2ZSBCaW5vbWlhbCwgc2luY2UgYXMgdXN1YWwgdGhlIFBvaXNzb24gcmVncmVzc2lvbiBzaG93cyBvdmVyZGlzcGVyc2lvbiAoZG9lcyBub3QgZml0IHRoZSBkYXRhIHdlbGwpIHNvIHRoYXQgd2UgY2Fubm90IHJlbHkgb24gdGhlIFBvaXNzb24gc3RhbmRhcmQgZXJyb3JzLiAKCmBgYHtyfQojIEZvciBydW5uaW5nIGxpbmVhciBjb3VudCByZWdyZXNzaW9ucywgd2UgbmVlZCB0byB3ZWlnaHQgYWxsIHRoZSByZWdyZXNzb3JzIGJ5IHRoZSBwb3B1bGF0aW9uIChzaW5jZSB3ZSBjYW4ndCB1c2UgdGhlICJvZmZzZXQoKSIgbWV0aG9kKQpyZWdkYXRhX2xpbiA8LSByZWdkYXRhIApyZWdkYXRhX2xpbiR5ZWFyaW5kIDwtIDEuMCoocmVnZGF0YSR5ZWFyID09ICIxODU0IikKcmVnZGF0YV9saW4kcG9wMTg1MSA8LSByZWdkYXRhX2xpbiRwb3AxODUxIC8gMTAwMDAKcmVnZGF0YV9saW5bLGMoInllYXJpbmQiLCJvdGhlcnBlcmMiLCJsYW1iZXRocGVyYyIsImxhbWJldGhwZXJjNTQiLCJwb3BfcGVyX2hvdXNlIildIDwtCglyZWdkYXRhX2xpblssYygieWVhcmluZCIsIm90aGVycGVyYyIsImxhbWJldGhwZXJjIiwibGFtYmV0aHBlcmM1NCIsInBvcF9wZXJfaG91c2UiKV0gKiByZWdkYXRhX2xpbiRwb3AxODUxCgojIFBvaXNzb24gcmVncmVzc2lvbiB3aXRoIGxpbmVhciAoaWRlbnRpdHkpIGxpbmsgZnVuY3Rpb24KcG9pczFwcm9wbl9saW4gPC0gZ2xtKGRlYXRocyB+IHBvcDE4NTEgKyBsYW1iZXRocGVyYzU0ICsgbGFtYmV0aHBlcmMgKyBvdGhlcnBlcmMgKyB5ZWFyaW5kCgktIDEgLCBmYW1pbHk9cG9pc3NvbihsaW5rPSJpZGVudGl0eSIpLCBkYXRhPXJlZ2RhdGFfbGluKQpwb2lzMXByb3BuX2xpbnJvYnVzdHNlIDwtIGNvZWZ0ZXN0KHBvaXMxcHJvcG5fbGluLCB2Y292ID0gdmNvdkhDKHBvaXMxcHJvcG5fbGluKSkKI3N1bW1hcnkocG9pczFwcm9wbl9saW4pCiNsb2dMaWsocG9pczFwcm9wbl9saW4pCgojIFBvaXNzb24gRkUgcmVncmVzc2lvbiB3aXRoIGxpbmVhciAoaWRlbnRpdHkpIGxpbmsgZnVuY3Rpb24KcG9pczJwcm9wbl9saW4gPC0gZ2xtKGRlYXRocyB+IHBvcDE4NTEgKyBsYW1iZXRocGVyYzU0ICsgbGFtYmV0aHBlcmMgKyBvdGhlcnBlcmMgKyB5ZWFyaW5kCgkrc3ViRGlzdHJpY3QgLSAxICwgZmFtaWx5PXBvaXNzb24obGluaz0iaWRlbnRpdHkiKSwgZGF0YT1yZWdkYXRhX2xpbikKcG9pczJwcm9wbl9saW5yb2J1c3RzZSA8LSBjb2VmdGVzdChwb2lzMnByb3BuX2xpbiwgdmNvdiA9IHZjb3ZIQyhwb2lzMnByb3BuX2xpbikpCiNzdW1tYXJ5KHBvaXMycHJvcG5fbGluKQojbG9nTGlrKHBvaXMycHJvcG5fbGluKQoKIyBOZWdhdGl2ZSBCaW5vbWlhbCB3aXRoIGxpbmVhciAoaWRlbnRpdHkpIGxpbmsgZnVuY3Rpb24KbmIxcHJvcG5fbGluIDwtIGdsbS5uYihkZWF0aHMgfiBwb3AxODUxICsgbGFtYmV0aHBlcmM1NCArIGxhbWJldGhwZXJjICsgb3RoZXJwZXJjICsgeWVhcmluZAoJIC0gMSwgbGluayA9IGlkZW50aXR5LCBkYXRhID0gcmVnZGF0YV9saW4pCm5iMXByb3BuX2xpbnJvYnVzdHNlIDwtIGNvZWZ0ZXN0KG5iMXByb3BuX2xpbiwgdmNvdiA9IHZjb3ZIQyhuYjFwcm9wbl9saW4pKQojc3VtbWFyeShuYjFwcm9wbl9saW4pCiNsb2dMaWsobmIxcHJvcG5fbGluKQoKIyBOZWdhdGl2ZSBCaW5vbWlhbCB3aXRoIGxpbmVhciAoaWRlbnRpdHkpIGxpbmsgZnVuY3Rpb24gJiBwb3B1bGF0aW9uIGRlbnNpdHkKbmIxcHJvcG5fbGluZGVuIDwtIGdsbS5uYihkZWF0aHMgfiBwb3AxODUxICsgbGFtYmV0aHBlcmM1NCArIGxhbWJldGhwZXJjICsgb3RoZXJwZXJjICsgeWVhcmluZAoJICsgcG9wX3Blcl9ob3VzZSAtIDEsIGxpbmsgPSBpZGVudGl0eSwgZGF0YSA9IHJlZ2RhdGFfbGluKQpuYjFwcm9wbl9saW5kZW5yb2J1c3RzZSA8LSBjb2VmdGVzdChuYjFwcm9wbl9saW5kZW4sIHZjb3YgPSB2Y292SEMobmIxcHJvcG5fbGluZGVuKSkKI3N1bW1hcnkobmIxcHJvcG5fbGluZGVuKQojbG9nTGlrKG5iMXByb3BuX2xpbmRlbikKCiMgRmluYWxseSwgRkVzCm5iMnByb3BuX2xpbiA8LSBnbG0ubmIoZGVhdGhzIH4gcG9wMTg1MSArIGxhbWJldGhwZXJjNTQgKyBsYW1iZXRocGVyYyArIG90aGVycGVyYyArIHllYXJpbmQKCSsgc3ViRGlzdHJpY3QgLSAxLCBsaW5rID0gaWRlbnRpdHksIGRhdGE9cmVnZGF0YV9saW4pCm5iMnByb3BuX2xpbnJvYnVzdHNlIDwtIGNvZWZ0ZXN0KG5iMnByb3BuX2xpbiwgdmNvdiA9IHZjb3ZIQyhuYjJwcm9wbl9saW4pKQojc3VtbWFyeShuYjJwcm9wbl9saW4pCiNsb2dMaWsobmIycHJvcG5fbGluKQoKCnN1bW1hcnkobmIxcHJvcG5fbGluZGVuKQoKYGBgCgpUaGlzIGxpbmVhciBOZWdhdGl2ZSBCaW5vbWlhbCByZWdyZXNzaW9uIGdpdmVzIHJlc3VsdHMgc2ltaWxhciB0byB0aGUgbGluZWFyIE9MUyByZWdyZXNzaW9uIGFib3ZlLiAKCiMjIyNDb3VudCAtIExvZyBSZWdyZXNzaW9ucyAoUG9pc3NvbiAmIE5lZ2F0aXZlIEJpbm9taWFsIFJlZ3Jlc3Npb25zKQoKVGhlIGxpbmVhciBjb3VudCByZWdyZXNzaW9ucyBpbmNvcnBvcmF0ZSB0aGUgYXNzdW1wdGlvbiB0aGF0IHRoZSByYW5kb20gdmFyaWFibGVzIGFyZSBjb3VudHMsIGJ1dCBsaW5lYXJpdHkgaXMgbm90IG5lY2Vzc2FyaWx5IGEgZ29vZCBhc3N1bXB0aW9uLiBJdCBpbXBvc2VzIHRoZSBhc3N1bXB0aW9uIHRoYXQgdGhlIHRyZWF0bWVudCBlZmZlY3QgcmVkdWNlcyBtb3J0YWxpdHkgcmF0ZXMgYnkgYSBmaXhlZCBhbW91bnQgaW5kZXBlbmRlbnQgb2YgdGhlIGJhc2UgbW9ydGFsaXR5IGxldmVsLiBBIHByb3BvcnRpb25hbCBvciByYXRpbyBleHByZXNzaW9uIHdvdWxkIGJlIG1vcmUgcmVhc29uYWJsZS4gVW5mb3J0dW5hdGVseSB0aGUgc3RhbmRhcmQgZXN0aW1hdGlvbiByb3V0aW5lcyBhcmUgYmFzZWQgb24gYSBsaW5lYXItaW4tbG9ncyBmb3JtOgoKJGxuKFJfe3N1YmRpcyx5cn0pID0gUl9TICsgKFJfTF57NTR9LVJfUykgKiBQX0wgKiBJX3t5cj0xODU0fSArIChSX0wtUl9TKSAqIFBfTCArIChSX08tUl9TKSAqIFBfTyArIFxkZWx0YV97NTR9ICogSV97eXI9MTg1NH0gKyBcZXBzaWxvbiQKCkl0IGlzIHRodXMgZGlmZmljdWx0IHRvIGltcG9zZSBleGFjdGx5IHRoZSBsaW5lYXIgcmVsYXRpb24gYmV0d2VlbiB0aGUgcmF0ZSBhbmQgdGhlIHBvcHVsYXRpb24gZnJhY3Rpb25zLiAoV2Ugd291bGQgbmVlZCBhIG5vbi1saW5lYXIgUG9pc3NvbiBhbmQgTmVnYXRpdmUgQmlub21pYWwgZml0dGluZyByb3V0aW5lLikgSW4gc3BpdGUgb2YgdGhpcyB3ZSBjYW4gcnVuIHRoZSBjb3VudCByZWdyZXNzaW9ucyBhbmQgd2UgZmluZCBlc3NlbnRpYWxseSB0aGUgc2FtZSBhcyB0aGUgbGluZWFyIHJlZ3Jlc3Npb25zOiB3YXRlciBzdXBwbHkgaXMgZHJhbWF0aWNhbGx5IGltcG9ydGFudCBhbmQgdGhlIGVmZmVjdCBvbiBtb3J0YWxpdHkgZHJhbWF0aWNhbGx5IGxhcmdlLiAKClRoZSBmb2xsb3dpbmcgY29kZSBjaHVuayBydW5zIGEgdmFyaWV0eSBvZiBQb2lzc29uIGFuZCBOZWdhdGl2ZSBCaW5vbWlhbCByZWdyZXNzaW9ucyBidXQgZGlzcGxheXMgb25seSB0aGUgTmVnYXRpdmUgQmlub21pYWwgd2l0aCBob3VzaW5nIGRlbnNpdHkuIAoKYGBge3J9CiMgUG9pc3NvbiB3aXRoIG5vIEZFIGFuZCBubyBob3VzaW5nIGRlbnNpdHkKcG9pczFwcm9wbiA8LSBnbG0oZGVhdGhzIH4gbGFtYmV0aHBlcmM1NCArIGxhbWJldGhwZXJjICsgb3RoZXJwZXJjICsgeWVhcgoJKyBvZmZzZXQobG9nKHBvcDE4NTEpKSwgZmFtaWx5PXBvaXNzb24sIGRhdGE9cmVnZGF0YSkKcG9pczFwcm9wbnJvYnVzdHNlIDwtIGNvZWZ0ZXN0KHBvaXMxcHJvcG4sIHZjb3YgPSB2Y292SEMocG9pczFwcm9wbikpCiNzdW1tYXJ5KHBvaXMxcHJvcG4pCiNsb2dMaWsocG9pczFwcm9wbikKCiMgUG9pc3NvbiB3aXRoIGhvdXNpbmcgZGVuc2l0eQpwb2lzMXByb3BuX2RlbiA8LSBnbG0oZGVhdGhzIH4gbGFtYmV0aHBlcmM1NCArIGxhbWJldGhwZXJjICsgb3RoZXJwZXJjICsgeWVhcgoJKyBwb3BfcGVyX2hvdXNlCSsgb2Zmc2V0KGxvZyhwb3AxODUxKSksIGZhbWlseT1wb2lzc29uLCBkYXRhPXJlZ2RhdGEpCnBvaXMxcHJvcG5fZGVucm9idXN0c2UgPC0gY29lZnRlc3QocG9pczFwcm9wbl9kZW4sIHZjb3YgPSB2Y292SEMocG9pczFwcm9wbl9kZW4pKQojc3VtbWFyeShwb2lzMXByb3BuX2RlbikKI2xvZ0xpayhwb2lzMXByb3BuX2RlbikKCiMgUG9pc3NvbiB3aXRoIGRpZmZlcmVudCByYXRlcyBieSBzdWItZGlzdHJpY3QgKGZpeGVkIGVmZmVjdHMpCnBvaXMycHJvcG4gPC0gZ2xtKGRlYXRocyB+IGxhbWJldGhwZXJjNTQgKyBsYW1iZXRocGVyYyArIG90aGVycGVyYyArIHllYXIKCSsgc3ViRGlzdHJpY3QgKyBvZmZzZXQobG9nKHBvcDE4NTEpKSwgZmFtaWx5PXBvaXNzb24sIGRhdGE9cmVnZGF0YSkKcG9pczJwcm9wbnJvYnVzdHNlIDwtIGNvZWZ0ZXN0KHBvaXMycHJvcG4sIHZjb3YgPSB2Y292SEMocG9pczJwcm9wbikpCiNzdW1tYXJ5KHBvaXMycHJvcG4pCiNsb2dMaWsocG9pczJwcm9wbikKCiMgTmVnYXRpdmUgQmlub21pYWwgd2l0aCBubyBGRSBhbmQgbm8gaG91c2luZyBkZW5zaXR5Cm5iMXByb3BuIDwtIGdsbS5uYihkZWF0aHMgfiBsYW1iZXRocGVyYzU0ICsgbGFtYmV0aHBlcmMgKyBvdGhlcnBlcmMgKyB5ZWFyCgkgKyBvZmZzZXQobG9nKHBvcDE4NTEpKSwgZGF0YT1yZWdkYXRhKQpuYjFwcm9wbnJvYnVzdHNlIDwtIGNvZWZ0ZXN0KG5iMXByb3BuLCB2Y292ID0gdmNvdkhDKG5iMXByb3BuKSkKI3N1bW1hcnkobmIxcHJvcG4pCiNsb2dMaWsobmIxcHJvcG4pCgojIEFsc28gcnVuIHdpdGggaG91c2luZyBkZW5zaXR5Cm5iMXByb3BuX2RlbiA8LSBnbG0ubmIoZGVhdGhzIH4gbGFtYmV0aHBlcmM1NCArIGxhbWJldGhwZXJjICsgb3RoZXJwZXJjICsgeWVhcgoJKyBwb3BfcGVyX2hvdXNlICsgb2Zmc2V0KGxvZyhwb3AxODUxKSksIGRhdGE9cmVnZGF0YSkKbmIxcHJvcG5fZGVucm9idXN0c2UgPC0gY29lZnRlc3QobmIxcHJvcG5fZGVuLCB2Y292ID0gdmNvdkhDKG5iMXByb3BuX2RlbikpCiNzdW1tYXJ5KG5iMXByb3BuX2RlbikKI2xvZ0xpayhuYjFwcm9wbl9kZW4pCgojIEZpbmFsbHksIEZFcwpuYjJwcm9wbiA8LSBnbG0ubmIoZGVhdGhzIH4gbGFtYmV0aHBlcmM1NCArIGxhbWJldGhwZXJjICsgb3RoZXJwZXJjICsgeWVhcgoJKyBzdWJEaXN0cmljdCArIG9mZnNldChsb2cocG9wMTg1MSkpLCBkYXRhPXJlZ2RhdGEpCm5iMnByb3Bucm9idXN0c2UgPC0gY29lZnRlc3QobmIycHJvcG4sIHZjb3YgPSB2Y292SEMobmIycHJvcG4pKQojc3VtbWFyeShuYjJwcm9wbikKI2xvZ0xpayhuYjJwcm9wbikKCnN1bW1hcnkobmIxcHJvcG5fZGVuKQoKYGBgCgpUaGUgcmVzdWx0IGZvciB0aGUgTmVnYXRpdmUgQmlub21pYWwgd2l0aCBob3VzaW5nIGRlbnNpdHkgaXMsIGFnYWluLCB0aGF0IHRoZSBlZmZlY3Qgb2YgY2xlYW4gd2F0ZXIgKHRoZSBMYW1iZXRoIGVmZmVjdCkgaXMgbGFyZ2UgYW5kIHN0YXRpc3RpY2FsbHkgc2lnbmlmaWNhbnQgKGNvZWZmaWNpZW50IGByIHJvdW5kKHN1bW1hcnkobmIxcHJvcG5fZGVuKSRjb2VmZmljaWVudHNbMiwxXSwzKWAsIHJhdGlvIGVmZmVjdCBgciByb3VuZChleHAoLXN1bW1hcnkobmIxcHJvcG5fZGVuKSRjb2VmZmljaWVudHNbMiwxXSksMilgLCB6IHJhdGlvIGByIHJvdW5kKHN1bW1hcnkobmIxcHJvcG5fZGVuKSRjb2VmZmljaWVudHNbMiwzXSwyKWApLiBUaGUgcmVncmVzc2lvbiBmaXRzIHRoZSBkYXRhIHJlYXNvbmFibHkgd2VsbCB3aGVuIG1lYXN1cmVkIGJ5IHRoZSBSZXNpZHVhbCBEZXZpYW5jZS4gCgojIyMjUG9wdWxhdGluZyBUYWJsZSB3aXRoIFN1bW1hcnkgU3RhdGlzdGljcwoKSSB1c2UgdGhlc2UgdGFibGVzIHRvIHN1bW1hcml6ZSB0aGUgZGlmZi1pbi1kaWZmIHJlZ3Jlc3Npb25zLCBidXQgZG8gbm90IGRpc3BsYXkgdGhlbSBoZXJlLiBZb3UgY2FuIGlmIHlvdSB3aXNoLiAKCkZpcnN0LCBhIGNvZGUgY2h1bmsgZm9yIHRoZSBsaW5lYXIgcmVncmVzc2lvbnMgKGJ1dCBhbHNvIGluY2x1ZGluZyB0aGUgTmVnYXRpdmUgQmlub21pYWwgd2l0aCBwb3B1bGF0aW9uIGRlbnNpdHkpCgoKYGBge3J9CiMgRmlyc3QsIGNyZWF0ZSB0aGUgZGF0YWZyYW1lcyBmb3IgcHJlZGljdGlvbi4gInByZWRpY3QiIGNhbiB0YWtlIGluIGEgZGF0YWZyYW1lIGJ1dCBmb3Igc29tZSByZWFzb24gaXQgb25seQojIHNlZW1zIHRvIHdvcmsgd2l0aCBhIGRhdGFmcmFtZSBmcm9tIGEgcmVncmVzc2lvbiAoYXQgbGVhc3QgSSBjb3VsZG4ndCBnZXQgaXQgdG8gd29yayBhbnkgb3RoZXIgd2F5KS4gCiMgVGhlIGlkZWEgaXMgdG8gdGFrZSBhICJtb2RlbC5kYXRhZnJhbWUiIGZyb20gb25lIG9mIHRoZSByZWdyZXNzaW9ucyAoanVzdCB0aGUgZmlyc3QgdGhyZWUgcm93cykgYW5kCiMgdGhlbiBtYW51YWxseSBpbnNlcnQgdGhlIHBvcHVsYXRpb24gcHJvcG9ydGlvbnMsIHllYXJzLCBldGMuIHRoYXQgd2Ugd2FudCB0byBwcmVkaWN0OgojICAtIFNvdXRod2FyayByYXRlLCAxODU0LCBhdmVyYWdlIGhvdXNpbmcgZGVuc2l0eSAoMXN0IHJvdywgTGFtYmV0aCBhbmQgIk90aGVyIiBwb3B1bGF0aW9uIHByb3BvcnRpb25zIDApCiMgIC0gTGFtYmV0aCByYXRlLCAxODU0LCBhdmVyYWdlIGhvdXNpbmcgZGVuc2l0eSAoMm5kIHJvdyBMYW1iZXRocGVyYz0xIGFuZCBsYW1iZXRocGVyYzU0PTEpCiMgIC0gIk90aGVyIiByYXRlLCAxODU0LCBhdmVyYWdlIGhvdXNpbmcgZGVuc2l0eSAoM3JkIHJvdywgb3RoZXJwZXJjPTEpCiMgVGhlIGlkZWEgaXMgdG8gdGFrZSB0aGUgZGF0YWZyYW1lIGZyb20gYSBmaXR0ZWQgbW9kZWwsIHRoZW4gb3Zlci13cml0ZSB0aGUgaW5kaWNhdG9ycyBmb3IgIkxhbWJldGgiLCAiT3RoZXIiCiMgV2UgbmVlZCBwb3B1bGF0aW9uLCBhbmQgaWYgd2UgcHV0IGluIDEwLDAwMCB0aGVuIHRoZSBjb3VudHMgd2lsbCBiZSBwZXIgMTAsMDAwIHBlb3BsZSB3aGljaCBpcyB0aGUgd2F5IHdlIAojIHdhbnQgdG8gcXVvdGUgcmF0ZXMuIApyZWdkYXRhX3ByZWQgPC0gbW9kZWwuZnJhbWUobmIxcHJvcG5fbGluZGVuKVsxOjMsXQpyZWdkYXRhX3ByZWQkbGFtYmV0aHBlcmMgPC0gYygwLDEsMCkgICMgUG9wdWxhdGlvbiBwcm9wb3J0aW9uIGZvciBMYW1iZXRoCnJlZ2RhdGFfcHJlZCRsYW1iZXRocGVyYzU0IDwtIGMoMCwxLDApICAjIFBvcHVsYXRpb24gcHJvcG9ydGlvbiBmb3IgTGFtYmV0aCAxOTU0CnJlZ2RhdGFfcHJlZCRvdGhlcnBlcmMgPC0gYygwLDAsMSkgICAjIFBvcHVsYXRpb24gcHJvcG9ydGlvbiBmb3IgIk90aGVyIgpyZWdkYXRhX3ByZWQkcG9wX3Blcl9ob3VzZSA8LSBtZWFuKHJlZ2RhdGEkcG9wX3Blcl9ob3VzZSkgICMgc2V0IHBvcHVsYXRpb24gcGVyIGhvdXNlIHRvIHRoZSBtZWFuCnJlZ2RhdGFfcHJlZCR5ZWFyIDwtICIxODU0IiAgICMgWWVhciB0byAxODU0CnJlZ2RhdGFfcHJlZCRgb2Zmc2V0KGxvZyhwb3AxODUxKSlgIDwtIGxvZygxMDAwMCkgICMgRm9yY2UgcG9wdWxhdGlvbiB0byBiZSAxMCwwMDAKcmVnZGF0YV9wcmVkJHBvcDE4NTEgPC0gMTAwMDAgICAgIyBGb3JjZSBwb3B1bGF0aW9uIHRvIGJlIDEwLDAwMAojIFNsaWdodCBkaWZmZXJlbmNlIGZvciBwcmVkaWN0aW5nIHdpdGggbGluZWFyIGNvdW50IG1vZGVscywgd2hlcmUgd2UgbmVlZCB0byBlbnRlciB0aGUKIyAiMTAsMDAwIiBwb3B1bGF0aW9uIGFzICIxIiAoc2luY2Ugd2UgZXN0aW1hdGVkIHBhcmFtZXRlcnMgcGVyIDEwLDAwMCkKcmVnZGF0YV9wcmVkbGluIDwtIHJlZ2RhdGFfcHJlZApyZWdkYXRhX3ByZWRsaW4kcG9wMTg1MSA8LSAxCnJlZ2RhdGFfcHJlZGxpbiR5ZWFyaW5kIDwtIDEKIyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0gIwojIENyZWF0ZSB0YWJsZSB3aXRoIHJlZ3Jlc3Npb24gcmVzdWx0cyAoZGlmZi1pbi1kaWZmcyBlc3RpbWF0ZSkgdXNpbmcgcm9idXN0IFNFcwojIGZvciBhbGwgZXhjZXB0IHRoZSBOQjEgKE5lZ2F0aXZlIEJpbm9taWFsIHdpdGhvdXQgc3ViLWRpc3RyaWN0IGZpeGVkIGVmZmVjdHMpCnJlZ3RhYmxlZGlkMTg1NmxpbiA8LSBtYXRyaXgoMCxucm93PTE2LG5jb2w9OSkKY29sbmFtZXMocmVndGFibGVkaWQxODU2bGluKSA8LSBjKCJMaW4gT0xTIiwiTGluIFBvaXNzb24iLCJMaW4gUG9pc3MgRkUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkxpbiBOZWcgQmlub20iLCJMaW4gTkIsIEhvdXNlIiwiTGluIE5CLCBGRSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiTG9nIE5CIiwiTG9nIE5CIEggZGVuIiwibG9nIE5CIEZFIikKcm93bmFtZXMocmVndGFibGVkaWQxODU2bGluKSA8LSBjKCJMYW1iZXRoIDE4NTQgZWZmZWN0IiwiU0UiLCJ6IHZhbHVlIiwKCSJsYW1iZXRoIHBlcmMiLCJ6IHZhbHVlIiwib3RoZXIgcGVyYyIsInogdmFsdWUiLCIxODU0IiwieiB2YWx1ZSIsCgkicG9wIGRlbnNpdHkiLCJ6IHZhbHVlIiwiQWRqIFJzcSAvIHJlc2lkIGRldiIsCSJSZXNpZCBEZXYgcC12YWx1ZSIsCgkiU291dGh3YXJrIDE4NTQgcmF0ZSIsIkxhbWJldGggMTg1NCByYXRlIiwiT3RoZXIgcmF0ZSIpCiMgUG9wdWxhdGUgdGhlIHRhYmxlIGZyb20gdGhlIHJlZ3Jlc3Npb25zCiMgRmlyc3QsIGRlZmluZSByb3dzIHRvIHB1dCBkYXRhIGludG8KeHRlZmZlY3QgPC0gYygxLDIsMykKeHJlc2lkZXYgPC0gMTIKeHJlc2lkZXZwdiA8LSAxMwp4bGFtYmV0aCA8LSBjKDQsNSkKeG90aGVyIDwtIGMoNiw3KQp4eWVhciA8LSBjKDgsOSkKeGhkZW4gPC0gYygxMCwxMSkKeG1vcnRhbGl0eSA8LSBjKDE0LDE1LDE2KQojIExpbmVhciBubyBwb3B1bGF0aW9uIGRlbnNpdHkKeHJvdyA8LSAxCnJlZ3RhYmxlZGlkMTg1Nmxpblt4dGVmZmVjdCx4cm93XSA8LSBzdW1tYXJ5KGxpbnByb3BuKSRjb2VmZmljaWVudHNbMixjKDEsMiwzKV0KcmVndGFibGVkaWQxODU2bGluW3hyZXNpZGV2LHhyb3ddIDwtIHN1bW1hcnkobGlucHJvcG4pJGFkai5yLnNxdWFyZWQKcmVndGFibGVkaWQxODU2bGluW3hsYW1iZXRoLHhyb3ddIDwtIHN1bW1hcnkobGlucHJvcG4pJGNvZWZmaWNpZW50c1szLGMoMSwzKV0KcmVndGFibGVkaWQxODU2bGluW3hvdGhlcix4cm93XSA8LSBzdW1tYXJ5KGxpbnByb3BuKSRjb2VmZmljaWVudHNbNCxjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4eWVhcix4cm93XSA8LSBzdW1tYXJ5KGxpbnByb3BuKSRjb2VmZmljaWVudHNbNSxjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4bW9ydGFsaXR5LHhyb3ddIDwtIHByZWRpY3QobGlucHJvcG4sbmV3ZGF0YT1yZWdkYXRhX3ByZWQpCiMgUG9pc3NvbiwgbGluZWFyIGZvcm0KeHJvdyA8LSAyCnJlZ3RhYmxlZGlkMTg1Nmxpblt4dGVmZmVjdCx4cm93XSA8LSBzdW1tYXJ5KHBvaXMxcHJvcG5fbGluKSRjb2VmZmljaWVudHNbMixjKDEsMiwzKV0KcmVndGFibGVkaWQxODU2bGluW3hyZXNpZGV2LHhyb3ddIDwtIHN1bW1hcnkocG9pczFwcm9wbl9saW4pJGRldmlhbmNlCnJlZ3RhYmxlZGlkMTg1Nmxpblt4bGFtYmV0aCx4cm93XSA8LSBzdW1tYXJ5KHBvaXMxcHJvcG5fbGluKSRjb2VmZmljaWVudHNbMyxjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4b3RoZXIseHJvd10gPC0gc3VtbWFyeShwb2lzMXByb3BuX2xpbikkY29lZmZpY2llbnRzWzQsYygxLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beHllYXIseHJvd10gPC0gc3VtbWFyeShwb2lzMXByb3BuX2xpbikkY29lZmZpY2llbnRzWzUsYygxLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beHJlc2lkZXZwdix4cm93XSA8LSAoMS1wY2hpc3Eoc3VtbWFyeShwb2lzMXByb3BuX2xpbikkZGV2aWFuY2Usc3VtbWFyeShwb2lzMXByb3BuX2xpbikkZGYucmVzaWR1YWwpKQpyZWd0YWJsZWRpZDE4NTZsaW5beG1vcnRhbGl0eSx4cm93XSA8LSBwcmVkaWN0KHBvaXMxcHJvcG5fbGluLG5ld2RhdGE9cmVnZGF0YV9wcmVkbGluKQojIE5lZ2F0aXZlIEJpbm9taWFsIEZFLCBsaW5lYXIgZm9ybQp4cm93IDwtIDMKcmVndGFibGVkaWQxODU2bGluW3h0ZWZmZWN0LHhyb3ddIDwtIHN1bW1hcnkocG9pczJwcm9wbl9saW4pJGNvZWZmaWNpZW50c1syLGMoMSwyLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beHJlc2lkZXYseHJvd10gPC0gc3VtbWFyeShwb2lzMnByb3BuX2xpbikkZGV2aWFuY2UKcmVndGFibGVkaWQxODU2bGluW3hsYW1iZXRoLHhyb3ddIDwtIHN1bW1hcnkocG9pczJwcm9wbl9saW4pJGNvZWZmaWNpZW50c1szLGMoMSwzKV0KcmVndGFibGVkaWQxODU2bGluW3hvdGhlcix4cm93XSA8LSBzdW1tYXJ5KHBvaXMycHJvcG5fbGluKSRjb2VmZmljaWVudHNbNCxjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4eWVhcix4cm93XSA8LSBzdW1tYXJ5KHBvaXMycHJvcG5fbGluKSRjb2VmZmljaWVudHNbNSxjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4cmVzaWRldnB2LHhyb3ddIDwtICgxLXBjaGlzcShzdW1tYXJ5KHBvaXMycHJvcG5fbGluKSRkZXZpYW5jZSxzdW1tYXJ5KHBvaXMycHJvcG5fbGluKSRkZi5yZXNpZHVhbCkpCiMgTmVnYXRpdmUgQmlub21pYWwsIGxpbmVhciBmb3JtCnhyb3cgPC0gNApyZWd0YWJsZWRpZDE4NTZsaW5beHRlZmZlY3QseHJvd10gPC0gc3VtbWFyeShuYjFwcm9wbl9saW4pJGNvZWZmaWNpZW50c1syLGMoMSwyLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beHJlc2lkZXYseHJvd10gPC0gc3VtbWFyeShuYjFwcm9wbl9saW4pJGRldmlhbmNlCnJlZ3RhYmxlZGlkMTg1Nmxpblt4bGFtYmV0aCx4cm93XSA8LSBzdW1tYXJ5KG5iMXByb3BuX2xpbikkY29lZmZpY2llbnRzWzMsYygxLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beG90aGVyLHhyb3ddIDwtIHN1bW1hcnkobmIxcHJvcG5fbGluKSRjb2VmZmljaWVudHNbNCxjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4eWVhcix4cm93XSA8LSBzdW1tYXJ5KG5iMXByb3BuX2xpbikkY29lZmZpY2llbnRzWzUsYygxLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beHJlc2lkZXZwdix4cm93XSA8LSAoMS1wY2hpc3Eoc3VtbWFyeShuYjFwcm9wbl9saW4pJGRldmlhbmNlLHN1bW1hcnkobmIxcHJvcG5fbGluKSRkZi5yZXNpZHVhbCkpCnJlZ3RhYmxlZGlkMTg1Nmxpblt4bW9ydGFsaXR5LHhyb3ddIDwtIHByZWRpY3QobmIxcHJvcG5fbGluLG5ld2RhdGE9cmVnZGF0YV9wcmVkbGluKQojIE5lZ2F0aXZlIEJpbm9taWFsIHBvcHVsYXRpb24gZGVuc2l0eSwgbGluZWFyIGZvcm0KeHJvdyA8LSA1CnJlZ3RhYmxlZGlkMTg1Nmxpblt4dGVmZmVjdCx4cm93XSA8LSBzdW1tYXJ5KG5iMXByb3BuX2xpbmRlbikkY29lZmZpY2llbnRzWzIsYygxLDIsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4cmVzaWRldix4cm93XSA8LSBzdW1tYXJ5KG5iMXByb3BuX2xpbmRlbikkZGV2aWFuY2UKcmVndGFibGVkaWQxODU2bGluW3hsYW1iZXRoLHhyb3ddIDwtIHN1bW1hcnkobmIxcHJvcG5fbGluZGVuKSRjb2VmZmljaWVudHNbMyxjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4b3RoZXIseHJvd10gPC0gc3VtbWFyeShuYjFwcm9wbl9saW5kZW4pJGNvZWZmaWNpZW50c1s0LGMoMSwzKV0KcmVndGFibGVkaWQxODU2bGluW3h5ZWFyLHhyb3ddIDwtIHN1bW1hcnkobmIxcHJvcG5fbGluZGVuKSRjb2VmZmljaWVudHNbNSxjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4aGRlbix4cm93XSA8LSBzdW1tYXJ5KG5iMXByb3BuX2xpbmRlbikkY29lZmZpY2llbnRzWzYsYygxLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beHJlc2lkZXZwdix4cm93XSA8LSAoMS1wY2hpc3Eoc3VtbWFyeShuYjFwcm9wbl9saW5kZW4pJGRldmlhbmNlLHN1bW1hcnkobmIxcHJvcG5fbGluZGVuKSRkZi5yZXNpZHVhbCkpCnJlZ3RhYmxlZGlkMTg1Nmxpblt4bW9ydGFsaXR5LHhyb3ddIDwtIHByZWRpY3QobmIxcHJvcG5fbGluZGVuLG5ld2RhdGE9cmVnZGF0YV9wcmVkbGluKQojIE5lZ2F0aXZlIEJpbm9taWFsIEZFLCBsb2dhcml0aG1pYyBmb3JtCnhyb3cgPC0gNgpyZWd0YWJsZWRpZDE4NTZsaW5beHRlZmZlY3QseHJvd10gPC0gc3VtbWFyeShuYjJwcm9wbl9saW4pJGNvZWZmaWNpZW50c1syLGMoMSwyLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beHJlc2lkZXYseHJvd10gPC0gc3VtbWFyeShuYjJwcm9wbl9saW4pJGRldmlhbmNlCnJlZ3RhYmxlZGlkMTg1Nmxpblt4bGFtYmV0aCx4cm93XSA8LSBzdW1tYXJ5KG5iMnByb3BuX2xpbikkY29lZmZpY2llbnRzWzMsYygxLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beG90aGVyLHhyb3ddIDwtIHN1bW1hcnkobmIycHJvcG5fbGluKSRjb2VmZmljaWVudHNbNCxjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4eWVhcix4cm93XSA8LSBzdW1tYXJ5KG5iMnByb3BuX2xpbikkY29lZmZpY2llbnRzWzUsYygxLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beHJlc2lkZXZwdix4cm93XSA8LSAoMS1wY2hpc3Eoc3VtbWFyeShuYjJwcm9wbl9saW4pJGRldmlhbmNlLHN1bW1hcnkobmIycHJvcG5fbGluKSRkZi5yZXNpZHVhbCkpCgojIE5lZ2F0aXZlIEJpbm9taWFsLCBsb2dhcml0aG1pYyBmb3JtCnhyb3cgPC0gNwpyZWd0YWJsZWRpZDE4NTZsaW5beHRlZmZlY3QseHJvd10gPC0gc3VtbWFyeShuYjFwcm9wbikkY29lZmZpY2llbnRzWzIsYygxLDIsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4cmVzaWRldix4cm93XSA8LSBzdW1tYXJ5KG5iMXByb3BuKSRkZXZpYW5jZQpyZWd0YWJsZWRpZDE4NTZsaW5beGxhbWJldGgseHJvd10gPC0gc3VtbWFyeShuYjFwcm9wbikkY29lZmZpY2llbnRzWzMsYygxLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beG90aGVyLHhyb3ddIDwtIHN1bW1hcnkobmIxcHJvcG4pJGNvZWZmaWNpZW50c1s0LGMoMSwzKV0KcmVndGFibGVkaWQxODU2bGluW3h5ZWFyLHhyb3ddIDwtIHN1bW1hcnkobmIxcHJvcG4pJGNvZWZmaWNpZW50c1s1LGMoMSwzKV0KcmVndGFibGVkaWQxODU2bGluW3hyZXNpZGV2cHYseHJvd10gPC0gKDEtcGNoaXNxKHN1bW1hcnkobmIxcHJvcG4pJGRldmlhbmNlLHN1bW1hcnkobmIxcHJvcG4pJGRmLnJlc2lkdWFsKSkKcmVndGFibGVkaWQxODU2bGluW3htb3J0YWxpdHkseHJvd10gPC0gZXhwKHByZWRpY3QobmIxcHJvcG4sbmV3ZGF0YT1yZWdkYXRhX3ByZWQpKQojIE5lZ2F0aXZlIEJpbm9taWFsIHBvcHVsYXRpb24gZGVuc2l0eSwgbG9nYXJpdGhtaWMgZm9ybQp4cm93IDwtIDgKcmVndGFibGVkaWQxODU2bGluW3h0ZWZmZWN0LHhyb3ddIDwtIHN1bW1hcnkobmIxcHJvcG5fZGVuKSRjb2VmZmljaWVudHNbMixjKDEsMiwzKV0KcmVndGFibGVkaWQxODU2bGluW3hyZXNpZGV2LHhyb3ddIDwtIHN1bW1hcnkobmIxcHJvcG5fZGVuKSRkZXZpYW5jZQpyZWd0YWJsZWRpZDE4NTZsaW5beGxhbWJldGgseHJvd10gPC0gc3VtbWFyeShuYjFwcm9wbl9kZW4pJGNvZWZmaWNpZW50c1szLGMoMSwzKV0KcmVndGFibGVkaWQxODU2bGluW3hvdGhlcix4cm93XSA8LSBzdW1tYXJ5KG5iMXByb3BuX2RlbikkY29lZmZpY2llbnRzWzQsYygxLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beHllYXIseHJvd10gPC0gc3VtbWFyeShuYjFwcm9wbl9kZW4pJGNvZWZmaWNpZW50c1s1LGMoMSwzKV0KcmVndGFibGVkaWQxODU2bGluW3hoZGVuLHhyb3ddIDwtIHN1bW1hcnkobmIxcHJvcG5fZGVuKSRjb2VmZmljaWVudHNbNixjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4cmVzaWRldnB2LHhyb3ddIDwtICgxLXBjaGlzcShzdW1tYXJ5KG5iMXByb3BuX2RlbikkZGV2aWFuY2Usc3VtbWFyeShuYjFwcm9wbl9kZW4pJGRmLnJlc2lkdWFsKSkKcmVndGFibGVkaWQxODU2bGluW3htb3J0YWxpdHkseHJvd10gPC0gZXhwKHByZWRpY3QobmIxcHJvcG5fZGVuLG5ld2RhdGE9cmVnZGF0YV9wcmVkKSkKIyBOZWdhdGl2ZSBCaW5vbWlhbCBGRSwgbG9nYXJpdGhtaWMgZm9ybQp4cm93IDwtIDkKcmVndGFibGVkaWQxODU2bGluW3h0ZWZmZWN0LHhyb3ddIDwtIHN1bW1hcnkobmIycHJvcG4pJGNvZWZmaWNpZW50c1syLGMoMSwyLDMpXQpyZWd0YWJsZWRpZDE4NTZsaW5beHJlc2lkZXYseHJvd10gPC0gc3VtbWFyeShuYjJwcm9wbikkZGV2aWFuY2UKcmVndGFibGVkaWQxODU2bGluW3hsYW1iZXRoLHhyb3ddIDwtIHN1bW1hcnkobmIycHJvcG4pJGNvZWZmaWNpZW50c1szLGMoMSwzKV0KcmVndGFibGVkaWQxODU2bGluW3hvdGhlcix4cm93XSA8LSBzdW1tYXJ5KG5iMnByb3BuKSRjb2VmZmljaWVudHNbNCxjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4eWVhcix4cm93XSA8LSBzdW1tYXJ5KG5iMnByb3BuKSRjb2VmZmljaWVudHNbNSxjKDEsMyldCnJlZ3RhYmxlZGlkMTg1Nmxpblt4cmVzaWRldnB2LHhyb3ddIDwtICgxLXBjaGlzcShzdW1tYXJ5KG5iMnByb3BuKSRkZXZpYW5jZSxzdW1tYXJ5KG5iMnByb3BuKSRkZi5yZXNpZHVhbCkpCgprYWJsZShyZWd0YWJsZWRpZDE4NTZsaW5bYygxLDMsOSwxMCwxMiwxMyksYygyLDQsNSldLGRpZ2l0cz0zLCBjYXB0aW9uID0gIlN1bW1hcnkgLSBEaWZmLWluLURpZmZzIENvbXBhcmlzb24gVXNpbmcgUG9wdWxhdGlvbiBQcm9wb3J0aW9ucyIsZm9ybWF0PSdwYW5kb2MnKQoKCmBgYAoKTm90ZSB0aGUgdmVyeSBsb3cgcHJlZGljdGVkIExhbWJldGggbW9ydGFsaXR5IHJhdGUgZm9yIHRoZSAiTGluZWFyIE5lZ2F0aXZlIEJpbm9taWFsIiBtb2RlbC4gSSBiZWxpZXZlIHRoaXMgaXMgYW4gYXJ0aWZhY3Qgb2YgdGhlIGxpbmVhciBmdW5jdGlvbmFsIGZvcm0gYW5kIHRoZSBlZmZlY3Qgb2YgaG91c2luZyBkZW5zaXR5LiBMaW5lYXJpdHkgZm9yY2VzIHRoZSBzYW1lICphZGRpdGl2ZSogZWZmZWN0IG9uIG1vcnRhbGl0eSByYXRlLCB3aGljaCBpcyBwcm9iYWJseSBub3QgYXBwcm9wcmlhdGUuIFNvdXRod2FyayByYXRlcyBhcmUgb24gdGhlIG9yZGVyIG9mIDE3MCBhbmQgTGFtYmV0aCBvbiB0aGUgb3JkZXIgb2YgMjAuIFdpdGggdGhlIGVzdGltYXRlZCBkZW5zaXR5IGNvZWZmaWNpZW50IHJvdWdobHkgMTAsIGlmIGhvdXNpbmcgZGVuc2l0eSBpcyBvbmUgcGVyY2VudGFnZSBwb2ludCBsb3dlciB0aGF0IHdvdWxkIGJlIGEgbW9kZXN0IGVmZmVjdCBvbiB0aGUgU291dGh3YXJrIHJhdGUgKGZyb20gMTcwIHRvIDE2MCkgYnV0IGEgaHVnZSBlZmZlY3Qgb24gTGFtYmV0aCAoZnJvbSAyMCB0byAxMCkuIExpbmVhcml0eSBpcyBwcm9iYWJseSBub3QgYSBnb29kIGFzc3VtcHRpb24gLSB0aGUgZWZmZWN0IGlzIG1vcmUgbGlrZWx5IHRvIGJlIG11bHRpcGxpY2F0aXZlLiAKClRoZSBwcm9ibGVtIHNob3dzIHVwIHBhcnRpY3VsYXJseSBiZWNhdXNlIG9mIHRoZSBwb3NpdGl2ZSBjb3JyZWxhdGlvbiBiZXR3ZWVuIGRlbnNpdHkgYW5kIHByb3BvcnRpb24gb2YgTGFtYmV0aCBjdXN0b21lcnM6IEl0IGFwcGVhcnMgdGhhdCBzdWItZGlzdHJpY3RzIHdpdGggYSBoaWdoZXIgcHJvcG9ydGlvbiBvZiBMYW1iZXRoIGN1c3RvbWVycyBhcmUgYWxzbyBoaWdoZXIgaG91c2luZyBkZW5zaXR5IChjb3JyZWxhdGlvbiBgciByb3VuZChjb3IocmVnZGF0YVtyZWdkYXRhWyxjKCJzdXBwbGllciIpXSA9PSAiU291dGh3YXJrVmF1eGhhbGxfTGFtYmV0aCIsInBvcF9wZXJfaG91c2UiXSxyZWdkYXRhW3JlZ2RhdGFbLGMoInN1cHBsaWVyIildID09ICJTb3V0aHdhcmtWYXV4aGFsbF9MYW1iZXRoIiwibGFtYmV0aHBlcmMiXSksMikgYCkuIAoKVGhlIG51bWJlcnMgcXVvdGVkIGluIHRoZSB0YWJsZSBhcmUgdGhlIHByZWRpY3RlZCByYXRlIGZvciAiYXZlcmFnZSIgaG91c2luZyBkZW5zaXR5LCBgciByb3VuZChtZWFuKHJlZ2RhdGEkcG9wX3Blcl9ob3VzZSksMilgIHBlb3BsZSBwZXIgaG91c2UuICBSZXBvcnRpbmcgdGhlIHByZWRpY3RlZCByYXRlIGZvciAiYXZlcmFnZSIgZGVuc2l0eSBwcm9iYWJseSBwdXNoZXMgdGhlIG1vcnRhbGl0eSBmb3IgTGFtYmV0aCBjdXN0b21lcnMgYmVsb3cgd2hhdCBpdCBzaG91bGQgYmUuIFVzaW5nIGEgbGFyZ2VyIGhvdXNpbmcgZGVuc2l0eSB3b3VsZCBnaXZlIGEgbW9yZSBhcHByb3ByaWF0ZSBwcmVkaWN0aW9uLiBOb3RlIHRoYXQgdGhlIGxpbmVhciBOZWdhdGl2ZSBCaW5vbWlhbCByZWdyZXNzaW9uIHJ1biB3aXRob3V0IGhvdXNpbmcgZGVuc2l0eSBwcmVkaWN0cyBhIHJhdGUgb2YgYHIgcm91bmQocHJlZGljdChuYjFwcm9wbl9saW4sbmV3ZGF0YT1yZWdkYXRhX3ByZWRsaW4pWzJdLDEpYC4gVGhlIGxvZ2FyaXRobWljIGZvcm0gb2YgdGhlIE5lZ2F0aXZlIEJpbm9taWFsLCB3aGljaCB3ZSB0aGluayBzaG91bGQgYmUgYmV0dGVyIGJlaGF2ZWQgYmVjYXVzZSBpdCBpcyBiYXNlZCBvbiBtdWx0aXBsaWNhdGl2ZSBlZmZlY3RzLCBwcmVkaWN0cyBgciByb3VuZCgxMDAwMCpleHAocHJlZGljdChuYjFwcm9wbixuZXdkYXRhPXJlZ2RhdGFfcHJlZGxpbilbMl0pLDEpYCBmb3Igbm8gaG91c2luZyBkZW5zaXR5LCBhbmQgYHIgcm91bmQoMTAwMDAqZXhwKHByZWRpY3QobmIxcHJvcG5fZGVuLG5ld2RhdGE9cmVnZGF0YV9wcmVkbGluKVsyXSksMSlgIHdpdGggKGF2ZXJhZ2UpIGhvdXNpbmcgZGVuc2l0eS4KCgpCZWxvdyBpcyBhIGNvZGUgY2h1bmsgZm9yIHRoZSB2YXJpb3VzIHBlcm11dGF0aW9ucyBvZiBjb3VudCByZWdyZXNzaW9ucyB3aXRoIHBvcHVsYXRpb24gcHJvcG9ydGlvbnMsIHNpeCByZWdyZXNzaW9ucyBpbiB0b3RhbDoKCisgUG9pc3NvbiBhbmQgTmVnYXRpdmUgQmlub21pYWwKKyBGb3IgZWFjaCwgbm8gcG9wdWxhdGlvbiBkZW5zaXR5LCB5ZXMgcG9wdWxhdGlvbiBkZW5zaXR5LCBzdWItZGlzdHJpY3QgZml4ZWQgZWZmZWN0cy4KCmBgYHtyfQojIENyZWF0ZSB0YWJsZSB3aXRoIHJlZ3Jlc3Npb24gcmVzdWx0cyAoZGlmZi1pbi1kaWZmcyBlc3RpbWF0ZSkgdXNpbmcgcm9idXN0IFNFcwojIGZvciBhbGwgZXhjZXB0IHRoZSBOQjEgKE5lZ2F0aXZlIEJpbm9taWFsIHdpdGhvdXQgc3ViLWRpc3RyaWN0IGZpeGVkIGVmZmVjdHMpCnJlZ3RhYmxlZGlkMTg1NiA8LSBtYXRyaXgoMCxucm93PTIxLG5jb2w9NikKY29sbmFtZXMocmVndGFibGVkaWQxODU2KSA8LSBjKCJQb2lzcyIsIlBvaXNzIHBvcCIsIlBvaXNzRkUiLCJOQiIsIk5CIHBvcCIsIk5CIEZFIikKcm93bmFtZXMocmVndGFibGVkaWQxODU2KSA8LSBjKCJMYW1iZXRoIDE4NTQgZWZmZWN0IiwiU0UiLCJ6IHZhbHVlIiwicC12YWx1ZSIsCgkicm9idXN0IFNFIiwieiB2YWx1ZSIsInJhdGlvIGVmZmVjdCIsCgkibGFtYmV0aCBwZXJjIiwiU0UiLCJ6IHZhbHVlIiwicC12YWx1ZSIsIm90aGVyIHBlcmMiLCJTRSIsInogdmFsdWUiLCJwLXZhbHVlIiwKCSJ0aGV0YSIsInJlc2lkIGRldiIsInBvcCBkZW4iLCJTRSIsInogdmFsdWUiLCJwLXZhbHVlIikKIyBQb3B1bGF0ZSB0aGUgdGFibGUgZnJvbSB0aGUgcmVncmVzc2lvbnMKIyBQb2lzcyBubyBwb3B1bGF0aW9uIGRlbnNpdHkKcmVndGFibGVkaWQxODU2W2MoMSwyLDMsNCksMV0gPC0gc3VtbWFyeShwb2lzMXByb3BuKSRjb2VmZmljaWVudHNbMixjKDEsMiwzLDQpXQpyZWd0YWJsZWRpZDE4NTZbYyg1LDYpLDFdIDwtIHBvaXMxcHJvcG5yb2J1c3RzZVsyLGMoMiwzKV0KcmVndGFibGVkaWQxODU2WzcsMV0gPC0gZXhwKHJlZ3RhYmxlZGlkMTg1NlsxLDFdKQpyZWd0YWJsZWRpZDE4NTZbYyg4LDksMTAsMTEpLDFdIDwtIHN1bW1hcnkocG9pczFwcm9wbikkY29lZmZpY2llbnRzWzMsYygxLDIsMyw0KV0KcmVndGFibGVkaWQxODU2W2MoMTIsMTMsMTQsMTUpLDFdIDwtIHN1bW1hcnkocG9pczFwcm9wbikkY29lZmZpY2llbnRzWzQsYygxLDIsMyw0KV0KcmVndGFibGVkaWQxODU2WzE3LDFdIDwtIHN1bW1hcnkocG9pczFwcm9wbikkZGV2aWFuY2UKIyBQb2lzcyBQb3B1bGF0aW9uIGRlbnNpdHkKcmVndGFibGVkaWQxODU2W2MoMSwyLDMsNCksMl0gPC0gc3VtbWFyeShwb2lzMXByb3BuX2RlbikkY29lZmZpY2llbnRzWzIsYygxLDIsMyw0KV0KcmVndGFibGVkaWQxODU2W2MoNSw2KSwyXSA8LSBwb2lzMXByb3BuX2RlbnJvYnVzdHNlWzIsYygyLDMpXQpyZWd0YWJsZWRpZDE4NTZbNywyXSA8LSBleHAocmVndGFibGVkaWQxODU2WzEsMl0pCnJlZ3RhYmxlZGlkMTg1NltjKDgsOSwxMCwxMSksMl0gPC0gc3VtbWFyeShwb2lzMXByb3BuX2RlbikkY29lZmZpY2llbnRzWzMsYygxLDIsMyw0KV0KcmVndGFibGVkaWQxODU2W2MoMTIsMTMsMTQsMTUpLDJdIDwtIHN1bW1hcnkocG9pczFwcm9wbl9kZW4pJGNvZWZmaWNpZW50c1s0LGMoMSwyLDMsNCldCnJlZ3RhYmxlZGlkMTg1NlsxNywyXSA8LSBzdW1tYXJ5KHBvaXMxcHJvcG5fZGVuKSRkZXZpYW5jZQpyZWd0YWJsZWRpZDE4NTZbYygxOCwxOSwyMCwyMSksMl0gPC0gc3VtbWFyeShwb2lzMXByb3BuX2RlbikkY29lZmZpY2llbnRzWzUsYygxLDIsMyw0KV0KIyBQb2lzcyBGaXhlZCBFZmZlY3RzCnJlZ3RhYmxlZGlkMTg1NltjKDEsMiwzLDQpLDNdIDwtIHN1bW1hcnkocG9pczJwcm9wbikkY29lZmZpY2llbnRzWzIsYygxLDIsMyw0KV0KcmVndGFibGVkaWQxODU2W2MoNSw2KSwzXSA8LSBwb2lzMnByb3Bucm9idXN0c2VbMixjKDIsMyldCnJlZ3RhYmxlZGlkMTg1Nls3LDNdIDwtIGV4cChyZWd0YWJsZWRpZDE4NTZbMSwzXSkKcmVndGFibGVkaWQxODU2W2MoOCw5LDEwLDExKSwzXSA8LSBzdW1tYXJ5KHBvaXMycHJvcG4pJGNvZWZmaWNpZW50c1szLGMoMSwyLDMsNCldCnJlZ3RhYmxlZGlkMTg1NltjKDEyLDEzLDE0LDE1KSwzXSA8LSBzdW1tYXJ5KHBvaXMycHJvcG4pJGNvZWZmaWNpZW50c1s0LGMoMSwyLDMsNCldCnJlZ3RhYmxlZGlkMTg1NlsxNywzXSA8LSBzdW1tYXJ5KHBvaXMycHJvcG4pJGRldmlhbmNlCiMgTkIgbm8gcG9wdWxhdGlvbiBkZW5zaXR5CnJlZ3RhYmxlZGlkMTg1NltjKDEsMiwzLDQpLDRdIDwtIHN1bW1hcnkobmIxcHJvcG4pJGNvZWZmaWNpZW50c1syLGMoMSwyLDMsNCldCnJlZ3RhYmxlZGlkMTg1NltjKDUsNiksNF0gPC0gbmIxcHJvcG5yb2J1c3RzZVsyLGMoMiwzKV0KcmVndGFibGVkaWQxODU2WzcsNF0gPC0gZXhwKHJlZ3RhYmxlZGlkMTg1NlsxLDNdKQpyZWd0YWJsZWRpZDE4NTZbYyg4LDksMTAsMTEpLDRdIDwtIHN1bW1hcnkobmIxcHJvcG4pJGNvZWZmaWNpZW50c1szLGMoMSwyLDMsNCldCnJlZ3RhYmxlZGlkMTg1NltjKDEyLDEzLDE0LDE1KSw0XSA8LSBzdW1tYXJ5KG5iMXByb3BuKSRjb2VmZmljaWVudHNbNCxjKDEsMiwzLDQpXQpyZWd0YWJsZWRpZDE4NTZbMTYsNF0gPC0gc3VtbWFyeShuYjFwcm9wbikkdGhldGEKcmVndGFibGVkaWQxODU2WzE3LDRdIDwtIHN1bW1hcnkobmIxcHJvcG4pJGRldmlhbmNlCiMgTkIgcG9wdWxhdGlvbiBkZW5zaXR5ICYgd2F0ZXIgY29tcGFueSBwZXJjZW50CnJlZ3RhYmxlZGlkMTg1NltjKDEsMiwzLDQpLDVdIDwtIHN1bW1hcnkobmIxcHJvcG5fZGVuKSRjb2VmZmljaWVudHNbMixjKDEsMiwzLDQpXQpyZWd0YWJsZWRpZDE4NTZbYyg1LDYpLDVdIDwtIG5iMXByb3BuX2RlbnJvYnVzdHNlWzIsYygyLDMpXQpyZWd0YWJsZWRpZDE4NTZbNyw1XSA8LSBleHAocmVndGFibGVkaWQxODU2WzEsNV0pCnJlZ3RhYmxlZGlkMTg1NltjKDgsOSwxMCwxMSksNV0gPC0gc3VtbWFyeShuYjFwcm9wbl9kZW4pJGNvZWZmaWNpZW50c1szLGMoMSwyLDMsNCldCnJlZ3RhYmxlZGlkMTg1NltjKDEyLDEzLDE0LDE1KSw1XSA8LSBzdW1tYXJ5KG5iMXByb3BuX2RlbikkY29lZmZpY2llbnRzWzQsYygxLDIsMyw0KV0KcmVndGFibGVkaWQxODU2WzE2LDVdIDwtIHN1bW1hcnkobmIxcHJvcG5fZGVuKSR0aGV0YQpyZWd0YWJsZWRpZDE4NTZbMTcsNV0gPC0gc3VtbWFyeShuYjFwcm9wbl9kZW4pJGRldmlhbmNlCnJlZ3RhYmxlZGlkMTg1NltjKDE4LDE5LDIwLDIxKSw1XSA8LSBzdW1tYXJ5KG5iMXByb3BuX2RlbikkY29lZmZpY2llbnRzWzUsYygxLDIsMyw0KV0KIyBOQiBGRXMKcmVndGFibGVkaWQxODU2W2MoMSwyLDMsNCksNl0gPC0gc3VtbWFyeShuYjJwcm9wbikkY29lZmZpY2llbnRzWzIsYygxLDIsMyw0KV0KcmVndGFibGVkaWQxODU2W2MoNSw2KSw2XSA8LSBuYjJwcm9wbnJvYnVzdHNlWzIsYygyLDMpXQpyZWd0YWJsZWRpZDE4NTZbNyw2XSA8LSBleHAocmVndGFibGVkaWQxODU2WzEsNl0pCnJlZ3RhYmxlZGlkMTg1NltjKDgsOSwxMCwxMSksNl0gPC0gc3VtbWFyeShuYjJwcm9wbikkY29lZmZpY2llbnRzWzMsYygxLDIsMyw0KV0KcmVndGFibGVkaWQxODU2W2MoMTIsMTMsMTQsMTUpLDZdIDwtIHN1bW1hcnkobmIycHJvcG4pJGNvZWZmaWNpZW50c1s0LGMoMSwyLDMsNCldCnJlZ3RhYmxlZGlkMTg1NlsxNiw2XSA8LSBzdW1tYXJ5KG5iMnByb3BuKSR0aGV0YQpyZWd0YWJsZWRpZDE4NTZbMTcsNl0gPC0gc3VtbWFyeShuYjJwcm9wbikkZGV2aWFuY2UKCgpgYGAKCiMjI1Bsb3RzIEZvciBQb2lzc29uIEVycm9yIEFuYWxhc3lzIC0gU2hvd2luZyB0b28gbXVjaCB2YXJpYXRpb24gCgpUaGUgUG9pc3NvbiByZWdyZXNzaW9ucyBkbyBub3QgYWNjb3VudCBmb3IgZW5vdWdoIG9mIHRoZSB2YXJpYXRpb24gLSB0aGUgZGF0YSBzZWVtIHRvIHNob3cgdGhhdCB0aGVyZSBpcyBtb3JlIHZhcmlhdGlvbiB0aGFuIHdvdWxkIGJlIGFjY291bnRlZCBmb3IgYnkgY29uc3RhbnQgbW9ydGFsaXR5IHJhdGVzIChjb25zdGFudCBmb3IgZWFjaCBzdXBwbGllciAtIFNvdXRod2FyayAmIFZhdXhoYWxsIENvbXBhbnksIExhbWJldGggQ29tcGFueSwgYW5kICJPdGhlciIpLCBldmVuIGlmIHdlIGFsbG93IGVhY2ggc3ViLWRpc3RyaWN0IHRvIHZhcnkuIFRoZSBkYXRhIHNlZW0gdG8gc2hvdyB0aGF0IHRoZXJlIGlzIHNvbWUgcmFuZG9tIHZhcmlhdGlvbiBpbiBtb3J0YWxpdHkgYWNyb3NzIHRoZSB5ZWFycyBhbmQgc3ViLWRpc3RyaWN0cywgYnV0IHRoYXQgZXZlbiBzbyB0aGVyZSBpcyBhIGxhcmdlIHRyZWF0bWVudCBlZmZlY3QgZm9yIExhbWJldGggQ29tcGFueSdzIGNsZWFuIHdhdGVyIHN1cHBseSBpbiAxODU0LiAKCmBgYHtyfQp4ZmFtaWx5IDwtIHByZXBlcnJkYXRhKHBvaXMxcHJvcG5fbGluLHNpbmdsZT0iY29udGludW91cyIsbGluaz0ibGluZWFyIikgICMgdGhpcyBmdW5jdGlvbiBtb2RpZmllcyBnbG9iYWwgZGF0YQoKCiNwZGYocGFzdGUoIi4uL3BhcGVyL2ZpZ3VyZXMvZXJyYmFyXyIsInBvaXMxX2RpZGNvbnRsaW4iLCJjcGRmIixzZXA9IiIpKQogIHBsb3QzKHgxODQ5LHgxODU0LCJTb3V0aHdhcmtWYXV4aGFsbCIscGFzdGUoIkZpcnN0LTEyIFNvdXRod2Fyay1vbmx5ICIseGZhbWlseSwiIDE4NDl2czE4NTQgIikpCiNkZXYub2ZmKCkKI3BkZihwYXN0ZSgiLi4vcGFwZXIvZmlndXJlcy9lcnJiYXJfIiwicG9pczFfZGlkY29udGxpbiIsImRwZGYiLHNlcD0iIikpCiAgcGxvdDMoeDE4NDkseDE4NTQsIlNvdXRod2Fya1ZhdXhoYWxsX0xhbWJldGgiLHBhc3RlKCJOZXh0LTE2IEpvaW50bHktU3VwcGxpZWQgIix4ZmFtaWx5LCIgMTg0OXZzMTg1NCAiKSkKI2Rldi5vZmYoKQpgYGAKCgpGaXJzdCwgd2UgY2FuIGxvb2sgYXQgdGhlIG1vc3QgYmFzaWMgUG9pc3NvbiByZWdyZXNzaW9uIChkb25lIGluIGxvZ2FyaXRobWljIGZvcm0pLCBpbmNsdWRpbmcgYSB0cmVhdG1lbnQgZWZmZWN0LCBhIHllYXIgZWZmZWN0LCBhbmQgYSBTb3V0aHdhcmstdmVyc3VzLUxhbWJldGggZWZmZWN0IGZvciAxODQ5LiAoVGhpcyB1c2VzIHRoZSBwbG90IGZ1bmN0aW9ucyBpbiAiU25vd1Bsb3RGbnMuciIuKSBUaGUgcmVkIGNpcmNsZXMgYXJlIHRoZSAxODQ5IHJhdGVzLiBUaGUgYmx1ZSBkaWFtb25kcyBhcmUgMTg1NCByYXRlcyBidXQgYWRqdXN0ZWQgZm9yIHRoZSAxODU0IGVmZmVjdCBhbmQgdGhlIHRyZWF0bWVudCBlZmZlY3QgLSBpbiBvdGhlciB3b3JkcyBtYWRlIGNvbXBhcmFibGUgdG8gdGhlIDE4NDkgcmF0ZXMuIFRoZSBlbXB0eSBjaXJjbGVzIGFyZSB0aGUgMTg0OSBwcmVkaWN0ZWQgcmF0ZXMsIHdpdGggYXBwcm94aW1hdGUgOTUlIGVycm9yIGJhcnMuIAoKVGhpcyBQb2lzc29uIHJlZ3Jlc3Npb24gZG9lcyBub3QgZml0IHRoZSBkYXRhIC0gbWFueSBvYnNlcnZhdGlvbnMgKDMzIG91dCBvZiA1NiBvciA1OSUpIGFyZSBvdXRzaWRlIHRoZSA5NSUgY29uZmlkZW5jZSBiYW5kcy4gVGhlcmUgaXMgc2ltcGx5IG1vcmUgdmFyaWF0aW9uIGFjcm9zcyBzdWItZGlzdHJpY3RzIHRoYW4gY291bGQgYmUgYWNjb3VudGVkIGZvciB3aXRoIGEgY29uc3RhbnQgcmF0ZSBmb3IgZWFjaCBvZiB0aGUgdGhyZWUgc3VwcGxpZXJzLgoKYGBge3J9CnhmYW1pbHkgPC0gcHJlcGVycmRhdGEocG9pczJwcm9wbl9saW4sImNvbnRpbnVvdXMiLGxpbms9ImxpbmVhciIpICAjIHRoaXMgZnVuY3Rpb24gbW9kaWZpZXMgZ2xvYmFsIGRhdGEKCiNwZGYocGFzdGUoIi4uL3BhcGVyL2ZpZ3VyZXMvZXJyYmFyXyIsInBvaXMyX2RpZGNvbnRsaW4iLCJjcGRmIixzZXA9IiIpKQogIHBsb3QzKHgxODQ5LHgxODU0LCJTb3V0aHdhcmtWYXV4aGFsbCIscGFzdGUoIkZpcnN0LTEyIFNvdXRod2Fyay1vbmx5IEZFIix4ZmFtaWx5LCIgMTg0OXZzMTg1NCAiKSkKI2Rldi5vZmYoKQoKI3BkZihwYXN0ZSgiLi4vcGFwZXIvZmlndXJlcy9lcnJiYXJfIiwicG9pczJfZGlkY29udGxpbiIsImRwZGYiLHNlcD0iIikpCiAgcGxvdDMoeDE4NDkseDE4NTQsIlNvdXRod2Fya1ZhdXhoYWxsX0xhbWJldGgiLHBhc3RlKCJOZXh0LTE2IEpvaW50bHktU3VwcGxpZWQgRkUiLHhmYW1pbHksIiAxODQ5dnMxODU0ICIpKQojZGV2Lm9mZigpCmBgYAoKQSB2ZXJ5IHJlYXNvbmFibGUgYWx0ZXJuYXRpdmUgaXMgdGhhdCByYXRlcyB2YXJ5IGFjcm9zcyBzdWItZGlzdHJpY3RzIC0gZWFjaCBzdWItZGlzdHJpY3QgaGFzIGl0J3Mgb3duIHJhdGUuIFRoaXMgaXMgYSBmaXhlZCBlZmZlY3RzIG1vZGVsLCBhIGZpeGVkLWNvZWZmaWNpZW50IG1vZGVsIGZvciByYXRlIHZhcmlhdGlvbiBhY3Jvc3Mgc3ViLWRpc3RyaWN0cy4gVGhpcyBleHBsYW5hdGlvbiBkb2VzIG5vdCBmaXQgdGhlIGRhdGEgd2VsbCwgYmVjYXVzZSB0aGVyZSBpcyBzdGlsbCB0b28gbXVjaCB2YXJpYXRpb24sIGluIHRoaXMgY2FzZSB2YXJpYXRpb24gYWNyb3NzIHllYXJzIGJ1dCB3aXRoaW4gc3ViLWRpc3RyaWN0cy4gVGhlcmUgYXJlIHJvdWdobHkgMTggb3V0IG9mIDU2IG9yIDMyJSBvZiBvYnNlcnZhdGlvbnMgb3V0c2lkZSB0aGUgOTUlIGNvbmZpZGVuY2UgYmFuZHMuCgoKYGBge3J9CnhmYW1pbHkgPC0gcHJlcGVycmRhdGEobmIxcHJvcG5fbGluLCJjb250aW51b3VzIixsaW5rPSJsaW5lYXIiKSAgIyB0aGlzIGZ1bmN0aW9uIG1vZGlmaWVzIGdsb2JhbCBkYXRhCgojcGRmKHBhc3RlKCIuLi9wYXBlci9maWd1cmVzL2VycmJhcl8iLCJuYjFfZGlkY29udGxpbiIsImNwZGYiLHNlcD0iIikpCiAgcGxvdDMoeDE4NDkseDE4NTQsIlNvdXRod2Fya1ZhdXhoYWxsIixwYXN0ZSgiRmlyc3QtMTIgU291dGh3YXJrLW9ubHkgIix4ZmFtaWx5LCIgMTg0OXZzMTg1NCAiKSkKI2Rldi5vZmYoKQoKI3BkZihwYXN0ZSgiLi4vcGFwZXIvZmlndXJlcy9lcnJiYXJfIiwibmIxX2RpZGNvbnRsaW4iLCJkcGRmIixzZXA9IiIpKQogIHBsb3QzKHgxODQ5LHgxODU0LCJTb3V0aHdhcmtWYXV4aGFsbF9MYW1iZXRoIixwYXN0ZSgiTmV4dC0xNiBKb2ludGx5LVN1cHBsaWVkICIseGZhbWlseSwiIDE4NDl2czE4NTQgIikpCiNkZXYub2ZmKCkKYGBgCgpBIHRoaXJkIGFsdGVybmF0aXZlIGlzIHRoYXQgbW9ydGFsaXR5IHJhdGVzIHZhcnkgYWNyb3NzIHN1Yi1kaXN0cmljdHMgYW5kIHllYXJzIGluIGEgcmFuZG9tIG1hbm5lci4gQSBOZWdhdGl2ZSBCaW5vbWlhbCBtb2RlbCBpcyBhIEdhbW1hLW1peHR1cmUgbW9kZWwgb2YgUG9pc3NvbnMgLSBpbmRpdmlkdWFscyBlYWNoIGhhdmUgYSBQb2lzc29uIGludGVuc2l0eSBmb3IgbW9ydGFsaXR5LCBidXQgdGhlIFBvaXNzb24gaW50ZW5zaXRpZXMgYXJlIGRpc3RyaWJ1dGVkIGFjcm9zcyB0aGUgcG9wdWxhdGlvbiBhY2NvcmRpbmcgdG8gYSBHYW1tYSBkaXN0cmlidXRpb24sIHdpdGggdGhlIHZhcmlhbmNlIG9mIHRoZSBHYW1tYSBwYXJhbWV0ZXIgdG8gYmUgZXN0aW1hdGVkLiAKClRoaXMgZmlndXJlIHNob3dzIHRoZSByZXN1bHRzLCBhbmQgdGhpcyBtb2RlbCBmaXRzIHRoZSBkYXRhIHJlYXNvbmFibHkgd2VsbC4gVGhlcmUgYXJlIDMgb3V0IG9mIDU2IG9yIDUuNDUgb2YgdGhlIG9ic2VydmF0aW9ucyBvdXRzaWRlIHRoZSBhcHByb3hpbWF0ZSA5NSUgY29uZmlkZW5jZSBiYW5kcy4gCgoKIyMjQ29uY2x1c2lvbiAtIFNub3cgd2FzIFJpZ2h0IC0gQ2xlYW4gV2F0ZXIgTWF0dGVycwoKVXNpbmcgdGhlIHBvcHVsYXRpb24gYnkgc3ViLWRpc3RyaWN0IHRvIG1lYXN1cmUgdGhlIGZyYWN0aW9uIG9mIGN1c3RvbWVycyBzdXBwbGllZCBieSB0aGUgU291dGh3YXJrICYgVmF1eGhhbGwgQ29tcGFueSwgdGhlIExhbWJldGggQ29tcGFueSwgYW5kIE90aGVyICh3ZWxscyBldGMuKSBzdHJvbmdseSBzdXBwb3J0cyBTbm93J3MgY29udGVudGlvbiBib3RoIHRoYXQgdGhlIGFjdHVhbCBhbmQgcHJlZGljdGVkIG1vcnRhbGl0eSAiYmVhciBhIGNsb3NlIHJlbGF0aW9uIiBhbmQgdGhhdCBuYXR1cmUgb2YgdGhlIHdhdGVyIHN1cHBseSBleGVydHMgYW4gIm92ZXJ3aGVsbWluZyBpbmZsdWVuY2UiLiAKCg==