Examining Snow’s 1855 Table VIII & 1856 Table V Using Population by Supplier

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 of Snow’s 1855 Table IX (quasi-randomized comparison) using sub-district population data from Snow 1856 Tables I and II, and District data from Snow 1856 Table VI. In 1855 Snow did not have population estimates by supplier These estimates became available with the publication of Simon 1856.

With population estimates by supplier there are now two sets of data that we can analyze:

  1. Quasi-Randomized Comparison by Sub-district: For the 7 weeks ending 26th August, for Southwark vs Lambeth. Snow (1855) Table VIII gives deaths by supplier (Southwark & Vauxhall, Lambeth, Other) for the first seven weeks (ending 26th August 1854). This formed the basis of Snow’s 1855 Table IX, measuring a treatment effect in a quasi-randomized trial. With population by supplier by sub-district we can examine each sub-district and test for the difference between Southwark versus Lambeth much more carefully. This only covers the first seven weeks (through 26th August) and we also have to recognize the problems with the population estimates which are more serious at the sub-district than District level.

  2. Quasi-Randomized Comparison by District: For the full 1854 outbreak (ending October), for Southwark, Lambeth, “Other”. Snow’s 1856 Table V gives deaths by supplier by nine Districts for the full 1854 period (ending October 1854).These data allow testing for the Southwark versus Lambeth effect in a quasi-randomized trial framework at a somewhat more aggregated level than the sub-district data above, but covering the full 1854 cholera outbreak

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 the data from Snow 1855 "On the mode of communication of cholera"
tablevii <- read.csv(file="Snow1855_TableVII.csv", header=TRUE, sep=",", skip=5,comment.char="#")
tableviii <- read.csv(file="Snow1855_TableVIII.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="#")

Calculate mortality rates for all sub-districts

# Calculate mortality rates for all sub-districts
tablei_1856$rateSouthwark <- 10000 * tablei_1856$deathsSouthwark / tablei_1856$southwark_pop
tablei_1856$rateLambeth <- 10000 * tablei_1856$deathsLambeth / tablei_1856$lambeth_pop
tablei_1856$rateboth <- 10000 * (tablei_1856$deathsSouthwark + tablei_1856$deathsLambeth) / 
     (tablei_1856$southwark_pop + tablei_1856$lambeth_pop)
tablei_1856$rateoverall <- 10000 * tablei_1856$deathsOverall / tablei_1856$pop1851

Count Regressions for Snow 1855 Table VIII (first 7 seeks, by sub-district)

Prepare Data

To run the regressions we need to stack the data, do some minor data clean-up (convert some non-numerics to numerics), and make an indicator variable for supplier (I use “xLambeth” so that “Southwark” is the excluded category - R excludes the first category by alphabetic sort).

# Prepare data for the sub-districts of the jointly-supplied "next 16" sub-districts
# There is data for Southwark-supplied customers and Lambeth-supplied customers 
# so there are two sets of observations for each sub-district
x1 <- subset(tablei_1856,supplier == "SouthwarkVauxhall_Lambeth")
xSouthwark <- x1[c("subDistrict","district","supplier")]
xSouthwark$deaths <- x1$deathsSouthwark
xSouthwark$population <- x1$southwark_pop
xSouthwark$rate <- 10000 * xSouthwark$deaths / xSouthwark$population
xSouthwark$seq <- c(seq(13,12+length(xSouthwark$deaths)))
xSouthwark$supplier <- "Southwark"
# the "as.character ..." is necessary because pop_per_house is stored as a factor, not a numeric
xSouthwark$pop_per_house <- as.numeric(as.character(x1$pop_per_house))  
#xSouthwark$dum1854 <- 0
xLambeth <- x1[c("subDistrict","district","supplier")]
xLambeth$deaths <- x1$deathsLambeth
xLambeth$population <- x1$lambeth_pop
xLambeth$rate <- 10000 * xLambeth$deaths / xLambeth$population
xLambeth$seq <- c(seq(13,12+length(xLambeth$deaths)))
xLambeth$supplier <- "xLambeth"
# the "as.character ..." is necessary because pop_per_house is stored as a factor, not a numeric
xLambeth$pop_per_house <- as.numeric(as.character(x1$pop_per_house))
regdata1855VIIjoint <- rbind(xSouthwark,xLambeth)
# Prepare data for the sub-districts of the Southwark-supplied "first 12" sub-districts
# There is data only for Southwark-supplied customers customers (although the population
# numbers quoted in Snow 1856 Tables I & II show population for Lambeth customers for some
# of these sub-districts, as Snow points out this is incorrect. Thus I am imposing assumption
# that population and counts for Lambeth-supplied customers for these sub-districts is zero)
# so there are two sets of observations for each sub-district
x1 <- subset(tablei_1856,supplier == "SouthwarkVauxhall")
xSouthwarkonly <- x1[c("subDistrict","district","supplier")]
xSouthwarkonly$deaths <- x1$deathsSouthwark
xSouthwarkonly$population <- x1$southwark_pop
xSouthwarkonly$rate <- 10000 * xSouthwarkonly$deaths / xSouthwarkonly$population
xSouthwarkonly$seq <- c(seq(1,length(xSouthwarkonly$deaths)))
xSouthwarkonly$supplier <- "Southwark"
# the "as.character ..." is necessary because pop_per_house is stored as a factor, not a numeric
xSouthwarkonly$pop_per_house <- as.numeric(as.character(x1$pop_per_house))  
#xSouthwark$dum1854 <- 0
regdata1855VIIboth <- rbind(xSouthwarkonly,xSouthwark,xLambeth)

Poisson Regressions

This code chunk runs the Poisson regressions, but I am not printing them out here.

# Poisson with same rate for all sub-districts (no sub-district fixed effects)
pois1_TableVIII <- glm(deaths ~ supplier 
    + offset(log(population)), family=poisson, data = regdata1855VIIjoint)
pois1_TableVIIIrobustse <- coeftest(pois1_TableVIII, vcov = vcovHC(pois1_TableVIII))
#summary(pois1_TableVIII))
#print(pois1_TableVIIIrobustse)
# Poisson with population (housing) density
pois1pop_TableVIII <- glm(deaths ~ supplier + pop_per_house 
    + offset(log(population)), family=poisson, data = regdata1855VIIjoint)
pois1pop_TableVIIIrobustse <- coeftest(pois1pop_TableVIII, vcov = vcovHC(pois1pop_TableVIII))
#summary(pois1pop_TableVIII))
#print(pois1pop_TableVIIIrobustse)
# Poisson with different rates by sub-district (fixed effects)
pois2_TableVIII <- glm(deaths ~ supplier + subDistrict
    + offset(log(population)), family=poisson, data = regdata1855VIIjoint)
pois2_TableVIIIrobustse <- coeftest(pois2_TableVIII, vcov = vcovHC(pois2_TableVIII))
#summary(pois2_TableVIII))
#print(pois2_TableVIIIrobustse)
# Quasi-Poisson, allowing dispersion to be a free parameter
poisQuasi <- glm(deaths ~ supplier 
    + offset(log(population)), family=quasipoisson, data = regdata1855VIIjoint)
poisQuasirobustse <- coeftest(poisQuasi, vcov = vcovHC(poisQuasi))
#summary(poisQuasi))

As with other regressions with cholera mortality data, these Poisson regressions have trouble with “overdispersion” - more variation across sub-districts than can be accounted for simply by variation in Poisson counts. I discuss and summarize the results below.

Negative Binomial Regressions

The following code chunk runs Negative Binomial regressions, both with and without population density. Including population density (housing density) tests whether crowding is an important contributing factor to cholera mortality, and whether difference in water supply is still important when we include density. The conclusion, discussed more below, is that population density really does not matter.

# Negative Binomial 
nb1_TableVIII <- glm.nb(deaths ~ supplier + offset(log(population)), data = regdata1855VIIjoint)
nb1_TableVIIIrobustse <- coeftest(nb1_TableVIII, vcov = vcovHC(nb1_TableVIII))
#summary(nb1_TableVIII))
#print(nb1_TableVIIIrobustse)
# Negative Binomial with district fixed effects
# Doesn't converge so comment out 
#nb2_TableVIII <- glm.nb(deaths ~ supplier + subDistrict
#   + offset(log(population)), data = regdata1855VIIjoint)
#nb2_TableVIIIrobustse <- coeftest(nb2_TableVIII, vcov = vcovHC(nb2_TableVIII))
#summary(nb2_TableVIII))
#print(nb2_TableVIIIrobustse)
# The following does robust standard errors. I cribbed this from
#  Start: 
#  https://stat.ethz.ch/pipermail/r-help/2008-May/161591.html
#Then click on "Next message:" for the second. Unfortunately, 
#at that point the thread broke (Paul next responded to the list 
#as a reply to an off-list message I sent him). So to continue, 
#next take Achim's URL above: 
#  https://stat.ethz.ch/pipermail/r-help/2008-May/161640.html
#and thereafter continue to click on "Next message:" until the 
#thread runs out. 
# cf https://stats.stackexchange.com/questions/117052/replicating-statas-robust-option-in-r
# STATA seems to use HC1 for robust BUT with n-1 instead of n-k (see "sandwich.pdf" and 
#   https://stats.stackexchange.com/questions/89999/how-to-replicate-statas-robust-binomial-glm-for-proportion-data-in-r)
# Negative Binomial regression with population density as a regressor
# Idea is to test Snow's 1856 assertion that density has no effect after
# taking into account the water supplier (Southwark vs Lambeth)
# Results seem to show that pop density is not significant.
# Remember - To get "Lambeth effect" need to take const + coeff(density)*avg(density)
nb1pop_TableVIII <- glm.nb(deaths ~ supplier + pop_per_house 
    + offset(log(population)), data = regdata1855VIIjoint)
nb1pop_TableVIIIrobustse <- coeftest(nb1pop_TableVIII, vcov = vcovHC(nb1pop_TableVIII))
#summary(nb1pop_TableVIII))
#print(nb1pop_TableVIIIrobustse)
nb1pop_TableVIIIboth <- glm.nb(deaths ~ supplier + pop_per_house 
    + offset(log(population)), data = regdata1855VIIboth)
nb1pop_TableVIIIbothrobustse <- coeftest(nb1pop_TableVIIIboth, vcov = vcovHC(nb1pop_TableVIIIboth))
#summary(nb1pop_TableVIIIboth))
#print(nb1pop_TableVIIIbothrobustse)

Summary Table

The following code chunk creates a large table with summary statistics from a variety of regressions for the 1855 Table VIII data:

  • Poisson: basic; including population (housing) density; Fixed effects; Quasi-Poisson (allowing for over-dispersion)
  • Negative Binomial: basic; including population (housing) density
# Create table with regression results 
regtable1855TableVIII <- matrix(0,nrow=16,ncol=8)
colnames(regtable1855TableVIII) <- c("Poiss","Poiss pop","Poiss FE","Poiss Quasi","NB","NB pop",
    "NB FE","NB all reg pop")
rownames(regtable1855TableVIII) <- c("Lambeth effect","SE","z-value","p value","robust SE","z value",
    "ratio effect",
    "theta","sub-dist FE","pop den",
    "SE","z-value","resid dev", "p-value","Southwark Pred Mort","Lambeth Pred Mort")
# Populate the table from the regressions
# calculate population for Southwark & Lambeth
xs <- sum(regdata1855VIIjoint$population[1:16])
xl <- sum(regdata1855VIIjoint$population[17:32])
# Poisson no sub-district FEs 
regtable1855TableVIII[c(1,2,3,4),1] <- summary(pois1_TableVIII)$coefficients[2,c(1,2,3,4)]
regtable1855TableVIII[c(5,6),1] <- pois1_TableVIIIrobustse[2,c(2,3)]
regtable1855TableVIII[7,1] <- exp(-regtable1855TableVIII[1,1])
regtable1855TableVIII[13,1] <- summary(pois1_TableVIII)$deviance
regtable1855TableVIII[14,1] <- 1 - pchisq(pois1_TableVIII$deviance,pois1_TableVIII$df.residual)
regtable1855TableVIII[15,1] <- 10000 * sum(pois1_TableVIII$fitted.values[1:16]) / xs
regtable1855TableVIII[16,1] <- 10000 * sum(pois1_TableVIII$fitted.values[17:32]) / xl
# Poisson population density
regtable1855TableVIII[c(1,2,3,4),2] <- summary(pois1pop_TableVIII)$coefficients[2,c(1,2,3,4)]
regtable1855TableVIII[c(5,6),2] <- pois1pop_TableVIIIrobustse[2,c(2,3)]
regtable1855TableVIII[7,2] <- exp(-regtable1855TableVIII[1,2])
regtable1855TableVIII[c(10,11,12),2] <- summary(pois1pop_TableVIII)$coefficients[3,c(1,2,3)]
regtable1855TableVIII[13,2] <- summary(pois1pop_TableVIII)$deviance
regtable1855TableVIII[14,2] <- 1 - pchisq(pois1pop_TableVIII$deviance,pois1pop_TableVIII$df.residual)
regtable1855TableVIII[15,2] <- 10000 * sum(pois1pop_TableVIII$fitted.values[1:16]) / xs
regtable1855TableVIII[16,2] <- 10000 * sum(pois1pop_TableVIII$fitted.values[17:32]) / xl
# Poisson yes sub-district FEs
regtable1855TableVIII[c(1,2,3,4),3] <- summary(pois2_TableVIII)$coefficients[2,c(1,2,3,4)]
regtable1855TableVIII[c(5,6),3] <- pois2_TableVIIIrobustse[2,c(2,3)]
regtable1855TableVIII[7,3] <- exp(-regtable1855TableVIII[1,3])
regtable1855TableVIII[13,3] <- summary(pois2_TableVIII)$deviance
regtable1855TableVIII[14,3] <- 1 - pchisq(pois2_TableVIII$deviance,pois2_TableVIII$df.residual)
regtable1855TableVIII[15,3] <- 10000 * sum(pois2_TableVIII$fitted.values[1:16]) / xs
regtable1855TableVIII[16,3] <- 10000 * sum(pois2_TableVIII$fitted.values[17:32]) / xl
# Quasi-Poisson no sub-district FEs
regtable1855TableVIII[c(1,2,3,4),4] <- summary(poisQuasi)$coefficients[2,c(1,2,3,4)]
regtable1855TableVIII[7,4] <- exp(-regtable1855TableVIII[1,4])
regtable1855TableVIII[13,4] <- summary(poisQuasi)$deviance
regtable1855TableVIII[14,4] <- 1 - pchisq(poisQuasi$deviance,poisQuasi$df.residual)
regtable1855TableVIII[15,4] <- 10000 * sum(poisQuasi$fitted.values[1:16]) / xs
regtable1855TableVIII[16,4] <- 10000 * sum(poisQuasi$fitted.values[17:32]) / xl
# NB no sub-district FEs
regtable1855TableVIII[c(1,2,3,4),5] <- summary(nb1_TableVIII)$coefficients[2,c(1,2,3,4)]
regtable1855TableVIII[c(5,6),5] <- nb1_TableVIIIrobustse[2,c(2,3)]
regtable1855TableVIII[7,5] <- exp(-regtable1855TableVIII[1,5])
regtable1855TableVIII[8,5] <- summary(nb1_TableVIII)$theta
regtable1855TableVIII[13,5] <- summary(nb1_TableVIII)$deviance
regtable1855TableVIII[14,5] <- 1 - pchisq(nb1_TableVIII$deviance,nb1_TableVIII$df.residual)
regtable1855TableVIII[15,5] <- 10000 * sum(nb1_TableVIII$fitted.values[1:16]) / xs
regtable1855TableVIII[16,5] <- 10000 * sum(nb1_TableVIII$fitted.values[17:32]) / xl
# NB including population density
regtable1855TableVIII[c(1,2,3,4),6] <- summary(nb1pop_TableVIII)$coefficients[2,c(1,2,3,4)]
regtable1855TableVIII[c(5,6),6] <- nb1pop_TableVIIIrobustse[2,c(2,3)]
regtable1855TableVIII[7,6] <- exp(-regtable1855TableVIII[1,6])
regtable1855TableVIII[c(10,11,12),6] <- summary(nb1pop_TableVIII)$coefficients[3,c(1,2,3)]
regtable1855TableVIII[8,6] <- summary(nb1pop_TableVIII)$theta
regtable1855TableVIII[13,6] <- summary(nb1pop_TableVIII)$deviance
regtable1855TableVIII[14,6] <- 1 - pchisq(nb1pop_TableVIII$deviance,nb1pop_TableVIII$df.residual)
regtable1855TableVIII[15,6] <- 10000 * sum(nb1pop_TableVIII$fitted.values[1:16]) / xs
regtable1855TableVIII[16,6] <- 10000 * sum(nb1pop_TableVIII$fitted.values[17:32]) / xl
# NB yes sub-district FEs
#regtable1855TableVIII[c(1,2,3,4),7] <- summary(nb2_TableVIII)$coefficients[2,c(1,2,3,4)]
#regtable1855TableVIII[c(5,6),7] <- nb2_TableVIIIrobustse[2,c(2,3)]
#regtable1855TableVIII[7,7] <- exp(-regtable1855TableVIII[1,7])
#regtable1855TableVIII[8,7] <- summary(nb2_TableVIII)$theta
#regtable1855TableVIII[13,7] <- summary(nb2_TableVIII)$deviance
#regtable1855TableVIII[15,7] <- 10000 * sum(nb2_TableVIII$fitted.values[1:16]) / xs
#regtable1855TableVIII[16,7] <- 10000 * sum(nb2_TableVIII$fitted.values[17:32]) / xl
# NB including population density, for all sub-district
regtable1855TableVIII[c(1,2,3,4),8] <- summary(nb1pop_TableVIIIboth)$coefficients[2,c(1,2,3,4)]
regtable1855TableVIII[c(5,6),8] <- nb1pop_TableVIIIbothrobustse[2,c(2,3)]
regtable1855TableVIII[7,8] <- exp(-regtable1855TableVIII[1,8])
regtable1855TableVIII[c(10,11,12),8] <- summary(nb1pop_TableVIIIboth)$coefficients[3,c(1,2,3)]
regtable1855TableVIII[8,8] <- summary(nb1pop_TableVIIIboth)$theta
regtable1855TableVIII[13,8] <- summary(nb1pop_TableVIIIboth)$deviance
regtable1855TableVIII[14,8] <- 1 - pchisq(nb1pop_TableVIIIboth$deviance,nb1pop_TableVIIIboth$df.residual)
regtable1855TableVIII[15,8] <- 10000 * sum(nb1pop_TableVIIIboth$fitted.values[1:28]) / sum(regdata1855VIIboth$population[1:28])
regtable1855TableVIII[16,8] <- 10000 * sum(nb1pop_TableVIIIboth$fitted.values[29:44]) / sum(regdata1855VIIboth$population[29:44])
kable(regtable1855TableVIII[c(1,3,10,12,13,14,15,16),c(2,3,6)],digits=3, caption = "Summary - Quasi-Randomized Regressions, 1855 Table VIII (7 weeks ending 26th Aug)",format='pandoc')
Summary - Quasi-Randomized Regressions, 1855 Table VIII (7 weeks ending 26th Aug)
Poiss pop Poiss FE NB pop
Lambeth effect -1.910 -1.867 -1.870
z-value -16.770 -15.749 -11.847
pop den -0.049 0.000 -0.068
z-value -1.037 0.000 -0.858
resid dev 78.364 24.871 38.714
p-value 0.000 0.052 0.107
Southwark Pred Mort 46.437 46.437 46.047
Lambeth Pred Mort 6.733 6.733 6.891

I am not printing out all the regressions (you can check the summary statistics in the table), but the results are:

  • Simple Poisson has a high Residual Deviance (“overdispersion”), implying that Poisson does not fit the data well, and that the estimated standard errors are too small.
  • Including population (housing) density has a negligible effect
  • Including sub-district fixed effects gives a Residual Deviance that is marginally significant (Residual Deviance = 24.87, p-value = 0.052). In other words Poisson with each sub-district having a different rate fits marginally.
  • Negative Binomial fits the data slightly better (in terms of Residual Deviance - it is higher than Poisson with Fixed Effects, but requires fewer explanatory variables to reduce the Deviance).
  • In all cases the “Lambeth Effect” is large (roughly -1.9 for a ratio effect of 6.5).
  • The “Lambeth Effect” is statistically significant (has a very large z-value). We cannot rely on the z-value for the basic Poisson regression (because the model does not fit well - the Residual Deviance is large), and we want to be cautious even with the Poisson FE model. But the Negative Binomial still has a very large z-value. Further, we can calculate robust standard errors for all the regressions, and these all have large z-values (8 or larger)

Graphs Showing Sub-District Variation

Graphing the actual versus fitted values, together with approximate standard errors, helps us see why the Poisson regression does not fit the data. The following code chunk produces the graph.

# "Worker" function to plot mean, predicted, and error bars
plot2_worker <- function(yseq, xmean,xlimdn,xpred,xlimup,title) {            
    xplot <- plot(xmean, yseq,
        xlim=range(c(xmean, xpred,xlimdn,xlimup)),
        ylim=rev(range(yseq)), col="red",
        main=title,xlab="Mortality rate actual (red filled) vs predicted (empty circle)",ylab="sub-district",
        pch=19)
    lines(xpred, yseq, type="p",
        xlim=range(c(xmean, xpred,xlimdn,xlimup)),
        ylim=rev(range(yseq)), 
        pch=1)
    # horizontal error bars
    xplot <- arrows(xlimdn, yseq, xlimup, yseq, length=0.05, angle=90, code=3,lty=3)
    xplot
}
# Poisson Regression Graph
# 2.5, mean, 97.5 quantiles for the "next 16" sub-districts, separately by Southwark vs 
# Lambeth populations, for Poisson regression
xx1count <- pois1_TableVIII$fitted.values
xx1rate <- 10000 * xx1count / regdata1855VIIjoint$population
x25 <- 10000 * qpois(.025,lambda=xx1count[1:16]) / regdata1855VIIjoint$population[1:16]
x975 <- 10000 * qpois(.975,lambda=xx1count[1:16]) / regdata1855VIIjoint$population[1:16]
#pdf(paste("../paper/figures/errbar_pois1_TableVIII","c.pdf",sep=""))
    p5 <- plot2_worker(13:28, regdata1855VIIjoint$rate[1:16],x25,xx1rate[1:16],x975,
        "Joint 1854 Poisson Act vs Pred, Southwark Supplied")

#dev.off()
x25 <- 10000 * qpois(.025,lambda=xx1count[17:32]) / regdata1855VIIjoint$population[17:32]
x975 <- 10000 * qpois(.975,lambda=xx1count[17:32]) / regdata1855VIIjoint$population[17:32]
x975 <- pmin(x975,20)
#pdf(paste("../paper/figures/errbar_pois1_TableVIII","d.pdf",sep=""))
    p6 <- plot2_worker(13:28, regdata1855VIIjoint$rate[17:32],x25,xx1rate[17:32],x975,
       "Joint 1854 Poisson Act vs Pred, Lambeth Supplied")

#dev.off()

The observed mortality rates (red circles) are quite variable compared with the fitted values, often falling outside the approximate error bars. The difference between Southwark & Vauxhall Co. customers (the first graph) versus Lambeth Co. customers is nonetheless very large.

We can accommodate the outliers within the error bars better either by allowing each sub-district to be different (including sub-district fixed effects), or by widening the error bars themselves (assuming the errors are Negative Binomial, essentially that the sub-districts have random mortality rates). For this set of data either approach works somewhat well, as shown by the Residual Deviance calculations in the table above.

The following two code chunks will produce graphs for Poisson FEs and Negative Binomial. I have commented out the actual plot command (the call to “plot2_worker”) but you can easily run these chunks yourself to see the graphs.

# Poisson Regression FE Graph
# 2.5, mean, 97.5 quantiles for the "next 16" sub-districts, separately by Southwark vs 
# Lambeth populations, for Poisson regression
xx1count <- pois2_TableVIII$fitted.values
xx1rate <- 10000 * xx1count / regdata1855VIIjoint$population
x25 <- 10000 * qpois(.025,lambda=xx1count[1:16]) / regdata1855VIIjoint$population[1:16]
x975 <- 10000 * qpois(.975,lambda=xx1count[1:16]) / regdata1855VIIjoint$population[1:16]
#pdf(paste("../paper/figures/errbar_pois2_TableVIII","c.pdf",sep=""))
#   p5 <- plot2_worker(13:28, regdata1855VIIjoint$rate[1:16],x25,xx1rate[1:16],x975, "Joint 1854 Poisson FE Act vs Pred, Southwark Supplied")
#dev.off()
x25 <- 10000 * qpois(.025,lambda=xx1count[17:32]) / regdata1855VIIjoint$population[17:32]
x975 <- 10000 * qpois(.975,lambda=xx1count[17:32]) / regdata1855VIIjoint$population[17:32]
x975 <- pmin(x975,20)
#pdf(paste("../paper/figures/errbar_pois2_TableVIII","d.pdf",sep=""))
#   p6 <- plot2_worker(13:28, regdata1855VIIjoint$rate[17:32],x25,xx1rate[17:32],x975,"Joint 1854 Poisson FE Act vs Pred, Lambeth Supplied")
#dev.off()
# Negative Binomial Population Density Graph
# Note the difference from the code chunks above - using qnbinom() rather than qpoiss()
# 2.5, mean, 97.5 quantiles for the "next 16" sub-districts, separately by Southwark vs 
# Lambeth populations
theta <- nb1pop_TableVIII$theta
xx1count <- nb1pop_TableVIII$fitted.values
xx1rate <- 10000 * xx1count / regdata1855VIIjoint$population
x25 <- 10000 * qnbinom(.025,size=theta,mu=xx1count[1:16]) / regdata1855VIIjoint$population[1:16]
x975 <- 10000 * qnbinom(.975,size=theta,mu=xx1count[1:16]) / regdata1855VIIjoint$population[1:16]
#pdf(paste("../paper/figures/errbar_nb1pop_TableVIII","c.pdf",sep=""))
#   p5 <- plot2_worker(13:28, regdata1855VIIjoint$rate[1:16],x25,xx1rate[1:16],x975,"Joint 1854 NegBinom+PopDen Act vs Pred, Southwark Supplied")
#dev.off()
x25 <- 10000 * qnbinom(.025,size=theta,mu=xx1count[17:32]) / regdata1855VIIjoint$population[17:32]
x975 <- 10000 * qnbinom(.975,size=theta,mu=xx1count[17:32]) / regdata1855VIIjoint$population[17:32]
x975 <- pmin(x975,20)
#pdf(paste("../paper/figures/errbar_nb1pop_TableVIII","d.pdf",sep=""))
#   p6 <- plot2_worker(13:28, regdata1855VIIjoint$rate[17:32],x25,xx1rate[17:32],x975,"Joint 1854 NegBinom+PopDen Act vs Pred, Lambeth Supplied")
#dev.off()

Conclusion

In summary, mortality data by sub-district for the seven weeks ending 26th August 1854, split by water supplier, strongly support the conclusion that water supply (dirty for Southwark & Vauxhall Co., clean for Lambeth Co.) has a very large impact on mortality. This conclusion holds in the presence of large variations across sub-districts. The effect of clean water is dramatically larger than, and is unaffected by, variation in housing density.

Count Regressions for Snow 1856 Table V (by District)

Snow 1856 Table V shows deaths by District (9 Districts rather than 32 sub-districts) and water source (Southwark Co, Lambeth Co, “Other”).

kable(tableV_1856[,c("district","deaths_southwark","deaths_lambeth","deaths_pumps","deaths_unascertained","deaths_total")],digits=3, caption = "Deaths by Supplier from 1856 Table V",format='pandoc')
Deaths by Supplier from 1856 Table V
district deaths_southwark deaths_lambeth deaths_pumps deaths_unascertained deaths_total
St. Saviour, Southwark 406 72 10 3 491
St. Olave, Southwark 277 0 8 28 313
Bermondsey 821 0 25 0 846
St. George, Southwark 388 99 0 56 543
Newington 458 58 2 176 694
Lambeth 525 138 24 240 927
Wandsworth 268 7 106 40 421
Camberwell 352 33 115 49 549
Rotherhithe 207 0 46 30 283
Greenwich & sub-districts, Sydenham 4 4 2 1 11
Houses not identified NA NA NA NA NA
TOTAL 3706 411 338 623 5078

There are two advantages and two disadvantages relative to Snow 1855 Table VIII:

Advantages: Deaths cover the complete epidemic (through October 1854) which matches Snow 1855 Table XII; Fewer problems with poor population estimates for Southwark versus Lambeth customers

Disadvantage: Many more “not ascertained” or “unascertained” cases in assigning deaths within District to water source (Southwark Co or Lambeth Co - the Registrar-General was far less careful collecting data after 26th August than Snow had been up to 26th August); Less geographic or location detail, with deaths reported by District rather than sub-district.

Prepare Data

There are two substantive modifications to the data that we have to make (apart from simply stacking the data to set up for regressions):

  • Allocate the “not ascertained” (or “unascertained”) deaths within a District to supplier, the Southwark & Vauxhall Co. or the Lambeth Co. As suggested by Snow, the simplest and most reasonable approach seems to be simply allocating by the within-District proportions (see Snow 1856 p. 247: “I, therefore, concluded that I could not be wrong in dividing the non-ascertained cases between the two companies in the same proportion as those which were ascertained”). Because we will use these data for count regressions (which require integer values), I round the result.
  • Remove counts for Bermondsey and Newington for “Other” because they show negative “Other” population (Southwark + Lambeth combined estimated population greater than 1851 census). This is not a good way to handle the problem but I can’t figure out any better
# Allocate "unascertained" within Registration District according to ratio of observed 
# Southwark vs Lambeth deaths
tableV_1856$deaths_southwark_adj <- tableV_1856$deaths_southwark + round(tableV_1856$deaths_unascertained*tableV_1856$deaths_southwark/(tableV_1856$deaths_southwark+tableV_1856$deaths_lambeth),0)
tableV_1856$deaths_lambeth_adj <- tableV_1856$deaths_lambeth + round(tableV_1856$deaths_unascertained*tableV_1856$deaths_lambeth/(tableV_1856$deaths_southwark+tableV_1856$deaths_lambeth),0)
x1 <- tableV_1856[1:9,]
# Southwark
xsouthwark <- x1[c("district","districtID","density_Snow","pop_southwark","deaths_southwark_adj")]
colnames(xsouthwark) <- c("district","districtID","density_Snow","pop","deaths_adj")
xsouthwark$supplier <- "Southwark"
# Lambeth
xlambeth <- x1[c("district","districtID","density_Snow","pop_lambeth","deaths_lambeth_adj")]
colnames(xlambeth) <- c("district","districtID","density_Snow","pop","deaths_adj")
xlambeth$supplier <- "xLambeth"
# Remove St. Olave, Southwark and Rotherhithe from Lambeth data (since 0 population)
xlambeth <- xlambeth[-c(2,9),]
# Other
xother <- x1[c("district","districtID","density_Snow","pop_lambeth","deaths_lambeth_adj")]
colnames(xother) <- c("district","districtID","density_Snow","pop","deaths_adj")
xother$pop <- x1$pop1851 - (x1$pop_southwark + x1$pop_lambeth)
xother$deaths_adj <- x1$deaths_pumps
xother$supplier <- "xOther"
# Remove Bermondsey & Newington & Lambeth because they show negative (or very low) pump population (Southwark + Lambeth
# combined estimated population greater than 1851 census)
# This is not a good way to handle the problem but I can't figure out any better
xother <- xother[-c(3,5,6),]
regdata_1856V_2supp <- rbind(xsouthwark,xlambeth)
regdata_1856V_3supp <- rbind(xsouthwark,xlambeth,xother)

Underlying Data for Quasi-Randomized Comparison

tableV_display <- tableV_1856[,c("district","deaths_southwark_adj","deaths_lambeth_adj","deaths_pumps","deaths_total","pop1851","pop_southwark","pop_lambeth")]
tableV_display$mortality_southwark <- 10000 * tableV_display$deaths_southwark_adj / tableV_display$pop_southwark
tableV_display$mortality_lambeth <- 10000 * tableV_display$deaths_lambeth_adj / tableV_display$pop_lambeth
tableV_display$mortality_pumps <- 10000 * tableV_display$deaths_pumps / (tableV_display$pop1851 - tableV_display$pop_southwark - tableV_display$pop_lambeth)
tableV_display$pop_pumps <- tableV_display$pop1851 - tableV_display$pop_southwark - tableV_display$pop_lambeth
tableV_display$percent_southwark <- 100 * tableV_display$pop_southwark / tableV_display$pop1851
tableV_display$percent_lambeth <- 100 * tableV_display$pop_lambeth / tableV_display$pop1851
tableV_display$percent_pumps <- 100 - tableV_display$percent_southwark - tableV_display$percent_lambeth
kable(tableV_display[c(1,2,3,4,5,6,7,8,9,12),c("district","pop1851","pop_southwark","mortality_southwark","pop_lambeth",
          "mortality_lambeth","pop_pumps","mortality_pumps")],digits=1, caption = "Mortality by Supplier from 1856 Table V (after allocating unassigned)",format='pandoc')
Mortality by Supplier from 1856 Table V (after allocating unassigned)
district pop1851 pop_southwark mortality_southwark pop_lambeth mortality_lambeth pop_pumps mortality_pumps
1 St. Saviour, Southwark 35731 19617 208.5 14201 50.7 1913 52.3
2 St. Olave, Southwark 19375 18638 163.6 0 NaN 737 108.5
3 Bermondsey 48128 57884 141.8 1785 0.0 -11541 -21.7
4 St. George, Southwark 51824 25039 172.9 23712 46.4 3073 0.0
5 Newington 64816 31940 192.2 33531 23.3 -655 -30.5
6 Lambeth 139325 54982 130.0 83786 22.4 557 430.9
7 Wandsworth 50764 18390 166.9 3870 20.7 28504 37.2
8 Camberwell 54667 23472 169.1 10478 35.3 20717 55.5
9 Rotherhithe 17805 14951 158.5 0 NaN 2854 161.2
12 TOTAL 482435 267625 159.4 171528 27.6 43282 78.1

Poisson Regressions

The following code chunk runs Poisson regression (but does not print out results): basic, with population density, Fixed Effects.

# -------  Now Count Regressions with Supplier = Southwark, Lambeth, and Other 
# Poisson with no density
pois1_TableV <- glm(deaths_adj ~ supplier 
    + offset(log(pop)), family=poisson, data=regdata_1856V_3supp)
pois1_TableVrobustse <- coeftest(pois1_TableV, vcov = vcovHC(pois1_TableV))
#summary(pois1_TableV)
# Poisson with yes density
pois1pop_TableV <- glm(deaths_adj ~ supplier + density_Snow
    + offset(log(pop)), family=poisson, data=regdata_1856V_3supp)
pois1pop_TableVrobustse <- coeftest(pois1pop_TableV, vcov = vcovHC(pois1pop_TableV))
#summary(pois1pop_TableV)
# Poisson with FE
poisFE_TableV <- glm(deaths_adj ~ supplier + district
    + offset(log(pop)), family=poisson, data=regdata_1856V_3supp)
poisFE_TableVrobustse <- coeftest(poisFE_TableV, vcov = vcovHC(poisFE_TableV))
#summary(poisFE_TableV)
# -------  Now Count Regressions with Supplier = Southwark, Lambeth
# Poisson with no density
pois1_TableV_2supp <- glm(deaths_adj ~ supplier 
    + offset(log(pop)), family=poisson, data=regdata_1856V_2supp)
pois1_TableV_2supprobustse <- coeftest(pois1_TableV_2supp, vcov = vcovHC(pois1_TableV_2supp))
#summary(pois1_TableV_2supp)
# Poisson with yes density
pois1pop_TableV_2supp <- glm(deaths_adj ~ supplier + density_Snow
    + offset(log(pop)), family=poisson, data=regdata_1856V_2supp)
pois1pop_TableV_2supprobustse <- coeftest(pois1pop_TableV_2supp, vcov = vcovHC(pois1pop_TableV_2supp))
#summary(pois1pop_TableV_2supp)
# Poisson with FE
poisFE_TableV_2supp <- glm(deaths_adj ~ supplier + district
    + offset(log(pop)), family=poisson, data=regdata_1856V_2supp)
poisFE_TableV_2supprobustse <- coeftest(poisFE_TableV_2supp, vcov = vcovHC(poisFE_TableV_2supp))
#summary(poisFE_TableV_2supp)

Negative Binomial Regressions

The following code chunk runs Negative Binomial regression (but does not print out results): basic and with population density.

# Negative Binomial with no density
nb1_TableV <- glm.nb(deaths_adj ~ supplier 
    + offset(log(pop)), data = regdata_1856V_3supp)
nb1_TableVrobustse <- coeftest(nb1_TableV, vcov = vcovHC(nb1_TableV))
#summary(nb1_TableV)
# Negative Binomial with yes density
nb1pop_TableV <- glm.nb(deaths_adj ~ supplier + density_Snow
    + offset(log(pop)), data = regdata_1856V_3supp)
nb1pop_TableVrobustse <- coeftest(nb1pop_TableV, vcov = vcovHC(nb1pop_TableV))
#summary(nb1pop_TableV)
# Negative Binomial with no density, only Southwark and Lambeth
nb1_TableV_2supp <- glm.nb(deaths_adj ~ supplier 
    + offset(log(pop)), data = regdata_1856V_2supp)
nb1_TableV_2supprobustse <- coeftest(nb1_TableV_2supp, vcov = vcovHC(nb1_TableV_2supp))
#summary(nb1_TableV_2supp)
# Negative Binomial with yes density, only Southwark & Lambeth
nb1pop_TableV_2supp <- glm.nb(deaths_adj ~ supplier + density_Snow
    + offset(log(pop)), data = regdata_1856V_2supp)
nb1pop_TableV_2supprobustse <- coeftest(nb1pop_TableV_2supp, vcov = vcovHC(nb1pop_TableV_2supp))
#summary(nb1pop_TableV_2supp)

Table with Summary

The following code chunk populates a table with summary statistics for various regressions:

  • Poisson: basic, with population (housing) density, District Fixed Effects
  • Negative Binomial: basic, with population (housing) density
# Create table with regression results for 1854 by Registration District (Southwark & Lambeth only) 
regtable1856TableV <- matrix(0,nrow=16,ncol=7)
colnames(regtable1856TableV) <- c("Poiss","Poiss pop","PoissFE","NB","NB pop","NB 2supp","NB pop 2supp")
rownames(regtable1856TableV) <- c("Lambeth effect","SE","z value","p-value",
    "robust SE","z value","ratio effect",
    "theta","resid dev","p-value","pop den","SE","z value","Southwark pred mort",
    "Lambeth pred mort","Other pred mort")
# Populate the table from the regressions
# Poiss no population density
regtable1856TableV[c(1,2,3,4),1] <- summary(pois1_TableV_2supp)$coefficients[2,c(1,2,3,4)]
regtable1856TableV[c(5,6),1] <- pois1_TableV_2supprobustse[2,c(2,3)]
regtable1856TableV[7,1] <- exp(-regtable1856TableV[1,1])
regtable1856TableV[9,1] <- summary(pois1_TableV_2supp)$deviance
regtable1856TableV[10,1] <- 1 - pchisq(pois1_TableV_2supp$deviance,pois1_TableV_2supp$df.residual)
regtable1856TableV[14,1] <- 10000 * sum(pois1_TableV_2supp$fitted.values[1:9]) / sum(regdata_1856V_3supp$pop[1:9])
regtable1856TableV[15,1] <- 10000 * sum(pois1_TableV_2supp$fitted.values[10:16]) / sum(regdata_1856V_3supp$pop[10:16])
#regtable1856TableV[16,1] <- 10000 * sum(pois1_TableV_2supp$fitted.values[17:22]) / sum(regdata_1856V_3supp$pop[17:22])
# Poiss yes population density
regtable1856TableV[c(1,2,3,4),2] <- summary(pois1pop_TableV_2supp)$coefficients[2,c(1,2,3,4)]
regtable1856TableV[c(5,6),2] <- pois1pop_TableV_2supprobustse[2,c(2,3)]
regtable1856TableV[7,2] <- exp(-regtable1856TableV[1,2])
regtable1856TableV[c(11,12,13),2] <- summary(pois1pop_TableV_2supp)$coefficients[3,c(1,2,3)]
regtable1856TableV[9,2] <- summary(pois1pop_TableV_2supp)$deviance
regtable1856TableV[10,2] <- 1 - pchisq(pois1pop_TableV_2supp$deviance,pois1pop_TableV_2supp$df.residual)
regtable1856TableV[14,2] <- 10000 * sum(pois1pop_TableV_2supp$fitted.values[1:9]) / sum(regdata_1856V_3supp$pop[1:9])
regtable1856TableV[15,2] <- 10000 * sum(pois1pop_TableV_2supp$fitted.values[10:16]) / sum(regdata_1856V_3supp$pop[10:16])
#regtable1856TableV[16,2] <- 10000 * sum(pois1pop_TableV_2supp$fitted.values[17:22]) / sum(regdata_1856V_3supp$pop[17:22])
# Poiss FE
regtable1856TableV[c(1,2,3,4),3] <- summary(poisFE_TableV_2supp)$coefficients[2,c(1,2,3,4)]
regtable1856TableV[c(5,6),3] <- poisFE_TableV_2supprobustse[2,c(2,3)]
regtable1856TableV[7,3] <- exp(-regtable1856TableV[1,3])
regtable1856TableV[9,3] <- summary(poisFE_TableV_2supp)$deviance
regtable1856TableV[10,3] <- 1 - pchisq(poisFE_TableV_2supp$deviance,poisFE_TableV_2supp$df.residual)
regtable1856TableV[14,3] <- 10000 * sum(poisFE_TableV_2supp$fitted.values[1:9]) / sum(regdata_1856V_3supp$pop[1:9])
regtable1856TableV[15,3] <- 10000 * sum(poisFE_TableV_2supp$fitted.values[10:16]) / sum(regdata_1856V_3supp$pop[10:16])
#regtable1856TableV[16,3] <- 10000 * sum(poisFE_TableV_2supp$fitted.values[17:22]) / sum(regdata_1856V_3supp$pop[17:22])
# Neg Binom no population density
regtable1856TableV[c(1,2,3,4),4] <- summary(nb1_TableV)$coefficients[2,c(1,2,3,4)]
regtable1856TableV[c(5,6),4] <- nb1_TableVrobustse[2,c(2,3)]
regtable1856TableV[7,4] <- exp(-regtable1856TableV[1,4])
regtable1856TableV[8,4] <- summary(nb1_TableV)$theta
regtable1856TableV[9,4] <- summary(nb1_TableV)$deviance
regtable1856TableV[10,4] <- 1 - pchisq(nb1_TableV$deviance,nb1_TableV$df.residual)
regtable1856TableV[14,4] <- 10000 * sum(nb1_TableV$fitted.values[1:9]) / sum(regdata_1856V_3supp$pop[1:9])
regtable1856TableV[15,4] <- 10000 * sum(nb1_TableV$fitted.values[10:16]) / sum(regdata_1856V_3supp$pop[10:16])
regtable1856TableV[16,4] <- 10000 * sum(nb1_TableV$fitted.values[17:22]) / sum(regdata_1856V_3supp$pop[17:22])
# Neg Binom yes population density
regtable1856TableV[c(1,2,3,4),5] <- summary(nb1pop_TableV)$coefficients[2,c(1,2,3,4)]
regtable1856TableV[c(5,6),5] <- nb1pop_TableVrobustse[2,c(2,3)]
regtable1856TableV[7,5] <- exp(-regtable1856TableV[1,5])
regtable1856TableV[8,5] <- summary(nb1pop_TableV)$theta
regtable1856TableV[c(11,12,13),5] <- summary(nb1pop_TableV)$coefficients[4,c(1,2,3)]
regtable1856TableV[9,5] <- summary(nb1pop_TableV)$deviance
regtable1856TableV[10,5] <- 1 - pchisq(nb1pop_TableV$deviance,nb1pop_TableV$df.residual)
regtable1856TableV[14,5] <- 10000 * sum(nb1pop_TableV$fitted.values[1:9]) / sum(regdata_1856V_3supp$pop[1:9])
regtable1856TableV[15,5] <- 10000 * sum(nb1pop_TableV$fitted.values[10:16]) / sum(regdata_1856V_3supp$pop[10:16])
regtable1856TableV[16,5] <- 10000 * sum(nb1pop_TableV$fitted.values[17:22]) / sum(regdata_1856V_3supp$pop[17:22])
# Neg Binom no population density, 2 suppliers (Southwark and Lambeth only)
regtable1856TableV[c(1,2,3,4),6] <- summary(nb1_TableV_2supp)$coefficients[2,c(1,2,3,4)]
regtable1856TableV[c(5,6),6] <- nb1_TableV_2supprobustse[2,c(2,3)]
regtable1856TableV[7,6] <- exp(-regtable1856TableV[1,6])
regtable1856TableV[8,6] <- summary(nb1_TableV_2supp)$theta
regtable1856TableV[9,6] <- summary(nb1_TableV_2supp)$deviance
regtable1856TableV[10,6] <- 1 - pchisq(nb1_TableV_2supp$deviance,nb1_TableV_2supp$df.residual)
regtable1856TableV[14,6] <- 10000 * sum(nb1_TableV_2supp$fitted.values[1:9]) / sum(regdata_1856V_3supp$pop[1:9])
regtable1856TableV[15,6] <- 10000 * sum(nb1_TableV_2supp$fitted.values[10:16]) / sum(regdata_1856V_3supp$pop[10:16])
# Neg Binom yes population density, 2 suppliers (Southwark and Lambeth only)
regtable1856TableV[c(1,2,3,4),7] <- summary(nb1pop_TableV_2supp)$coefficients[2,c(1,2,3,4)]
regtable1856TableV[c(5,6),7] <- nb1pop_TableV_2supprobustse[2,c(2,3)]
regtable1856TableV[7,7] <- exp(-regtable1856TableV[1,7])
regtable1856TableV[8,7] <- summary(nb1pop_TableV_2supp)$theta
regtable1856TableV[c(11,12,13),7] <- summary(nb1pop_TableV_2supp)$coefficients[3,c(1,2,3)]
regtable1856TableV[9,7] <- summary(nb1pop_TableV_2supp)$deviance
regtable1856TableV[10,7] <- 1 - pchisq(nb1pop_TableV_2supp$deviance,nb1pop_TableV_2supp$df.residual)
regtable1856TableV[14,7] <- 10000 * sum(nb1pop_TableV_2supp$fitted.values[1:9]) / sum(regdata_1856V_3supp$pop[1:9])
regtable1856TableV[15,7] <- 10000 * sum(nb1pop_TableV_2supp$fitted.values[10:16]) / sum(regdata_1856V_3supp$pop[10:16])
kable(regtable1856TableV[c(1,2,3,5,6,7,8,9,10,11,12,13,14,15,16),c(1,3,6,7)],digits=3, caption = "Summary - Quasi-Randomized Regressions, 1856 Table V (by District, full 1854 epidemic)",format='pandoc')
Summary - Quasi-Randomized Regressions, 1856 Table V (by District, full 1854 epidemic)
Poiss PoissFE NB 2supp NB pop 2supp
Lambeth effect -1.716 -1.701 -1.659 -1.662
SE 0.048 0.049 0.127 0.120
z value -36.056 -34.478 -13.015 -13.894
robust SE 0.257 NaN 0.195 0.187
z value -6.670 NaN -8.505 -8.904
ratio effect 5.561 5.477 5.256 5.268
theta 0.000 0.000 21.134 25.032
resid dev 165.601 41.343 24.860 24.686
p-value 0.000 0.000 0.036 0.025
pop den 0.000 0.000 0.000 0.116
SE 0.000 0.000 0.000 0.076
z value 0.000 0.000 0.000 1.524
Southwark pred mort 159.977 159.977 166.901 167.202
Lambeth pred mort 28.769 28.769 31.754 31.535
Other pred mort 0.000 0.000 0.000 0.000

Conclusion

I am not printing out all the regressions (you can check the summary statistics in the table), but the results are broadly the same as for the first seven weeks:

  • Simple Poisson has a high Residual Deviance, implying that Poisson does not fit the data well - and that the estimated standard errors are too small.
  • Including population (housing) density shows density has a negligible effect
  • Including sub-district fixed effects does not reduce the Residual Deviance enough to fit the data.
  • Negative Binomial fits the data slightly better (in terms of Residual Deviance - it is marginally small enough).
  • In all cases the “Lambeth Effect” is large - (roughly -1.7 for a ratio effect of 5.5)
  • The “Lambeth Effect” is statistically significant (has a very large z-value). We cannot rely on the z-value for the basic Poisson regression (because the model does not fit well - the Residual Deviance is large), and we want to be cautious with all these models. Even using robust standard errors, however, we find z-values of 5 or larger.

Overall Conclusion

Snow recognized the value of his “Grand Experiment” - the near-randomization of customers in South London. In his 1855 “On the mode …” he did not have the population data to test carefully, and with the population data in his 1856 “Cholera and the water supply …” he did not have the statistical framework or the tools for formal hypothesis testing.

We, however, do have the necessary framework and tools. Whether using the first seven weeks by sub-district from 1855 Table VIII or the full 1854 outbreak by District from 1856 Table V, the results are unambiguous: customers supplied with clean water by the Lambeth Co. had dramatically lower mortality than customers supplied by the Southwark & Vauxhall Co. (or supplied by “Other”). Snow recognized that the mixing of customers was a strong argument that ruled out virtually all other confounding factors - income, sex, age, social status, weather - since customers that were randomly mixed and in close proximity would either be mixed across these variables or would share the same influence (weather, for example). With our statistical tools we can more formally confirm what Snow saw in the data - clean water was more important than any of the other factors he (or we) could think of.

LS0tCnRpdGxlOiAiSm9obiBTbm93IFByb2plY3QgLSBRdWFzaS1SYW5kb21pemVkIHdpdGggUG9wdWxhdGlvbiBEYXRhIgphdXRob3I6ICJbVGhvbWFzIENvbGVtYW5dKGh0dHA6Ly93d3cuaGlsZXJ1bi5vcmcvZWNvbikiCm91dHB1dDogaHRtbF9ub3RlYm9vawotLS0KIyBFeGFtaW5pbmcgU25vdydzIDE4NTUgVGFibGUgVklJSSAmIDE4NTYgVGFibGUgViBVc2luZyBQb3B1bGF0aW9uIGJ5IFN1cHBsaWVyCgojIyMjIFNlZSAiQ2F1c2FsaXR5IGluIHRoZSBUaW1lIG9mIENob2xlcmEiIHdvcmtpbmcgcGFwZXIgYXQgaHR0cHM6Ly9wYXBlcnMuc3Nybi5jb20vYWJzdHJhY3Q9MzI2MjIzNCBhbmQgbXkgW0pvaG4gU25vdyBwcm9qZWN0IHdlYnNpdGVdKGh0dHA6Ly93d3cuaGlsZXJ1bi5vcmcvZWNvbi9wYXBlcnMvc25vdykKCiMjIyMgVGhpcyBub3RlYm9vayBpcyBsaWNlbnNlZCB1bmRlciB0aGUgW0JTRCAyLUNsYXVzZSBMaWNlbnNlXShodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL0JTRC0yLUNsYXVzZSkKCiMjIyBJbnRyb2R1Y3Rpb24KClRoaXMgbm90ZWJvb2sgZXh0ZW5kcyB0aGUgYW5hbHlzaXMgb2YgU25vdydzIDE4NTUgVGFibGUgSVggKHF1YXNpLXJhbmRvbWl6ZWQgY29tcGFyaXNvbikgdXNpbmcgc3ViLWRpc3RyaWN0IHBvcHVsYXRpb24gZGF0YSBmcm9tIFNub3cgMTg1NiBUYWJsZXMgSSBhbmQgSUksIGFuZCBEaXN0cmljdCBkYXRhIGZyb20gU25vdyAxODU2IFRhYmxlIFZJLiBJbiAxODU1IFNub3cgZGlkIG5vdCBoYXZlIHBvcHVsYXRpb24gZXN0aW1hdGVzIGJ5IHN1cHBsaWVyIFRoZXNlIGVzdGltYXRlcyBiZWNhbWUgYXZhaWxhYmxlIHdpdGggdGhlIHB1YmxpY2F0aW9uIG9mIFNpbW9uIDE4NTYuIAoKV2l0aCBwb3B1bGF0aW9uIGVzdGltYXRlcyBieSBzdXBwbGllciB0aGVyZSBhcmUgbm93IHR3byBzZXRzIG9mIGRhdGEgdGhhdCB3ZSBjYW4gYW5hbHl6ZToKCjEuICoqUXVhc2ktUmFuZG9taXplZCBDb21wYXJpc29uIGJ5IFN1Yi1kaXN0cmljdCoqOiBGb3IgdGhlIDcgd2Vla3MgZW5kaW5nIDI2dGggQXVndXN0LCBmb3IgU291dGh3YXJrIHZzIExhbWJldGguIFNub3cgKDE4NTUpIFRhYmxlIFZJSUkgZ2l2ZXMgZGVhdGhzIGJ5IHN1cHBsaWVyIChTb3V0aHdhcmsgJiBWYXV4aGFsbCwgTGFtYmV0aCwgT3RoZXIpIGZvciB0aGUgZmlyc3Qgc2V2ZW4gd2Vla3MgKGVuZGluZyAyNnRoIEF1Z3VzdCAxODU0KS4gVGhpcyBmb3JtZWQgdGhlIGJhc2lzIG9mIFNub3cncyAxODU1IFRhYmxlIElYLCBtZWFzdXJpbmcgYSB0cmVhdG1lbnQgZWZmZWN0IGluIGEgcXVhc2ktcmFuZG9taXplZCB0cmlhbC4gV2l0aCBwb3B1bGF0aW9uIGJ5IHN1cHBsaWVyIGJ5IHN1Yi1kaXN0cmljdCB3ZSBjYW4gZXhhbWluZSBlYWNoIHN1Yi1kaXN0cmljdCBhbmQgdGVzdCBmb3IgdGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBTb3V0aHdhcmsgdmVyc3VzIExhbWJldGggbXVjaCBtb3JlIGNhcmVmdWxseS4gVGhpcyBvbmx5IGNvdmVycyB0aGUgZmlyc3Qgc2V2ZW4gd2Vla3MgKHRocm91Z2ggMjZ0aCBBdWd1c3QpIGFuZCB3ZSBhbHNvIGhhdmUgdG8gcmVjb2duaXplIHRoZSBwcm9ibGVtcyB3aXRoIHRoZSBwb3B1bGF0aW9uIGVzdGltYXRlcyB3aGljaCBhcmUgbW9yZSBzZXJpb3VzIGF0IHRoZSBzdWItZGlzdHJpY3QgdGhhbiBEaXN0cmljdCBsZXZlbC4gCgoyLiAqKlF1YXNpLVJhbmRvbWl6ZWQgQ29tcGFyaXNvbiBieSBEaXN0cmljdCoqOiBGb3IgdGhlIGZ1bGwgMTg1NCBvdXRicmVhayAoZW5kaW5nIE9jdG9iZXIpLCBmb3IgU291dGh3YXJrLCBMYW1iZXRoLCDigJxPdGhlcuKAnS4gU25vdydzIDE4NTYgVGFibGUgViBnaXZlcyBkZWF0aHMgYnkgc3VwcGxpZXIgYnkgbmluZSBEaXN0cmljdHMgZm9yIHRoZSBmdWxsIDE4NTQgcGVyaW9kIChlbmRpbmcgT2N0b2JlciAxODU0KS5UaGVzZSBkYXRhIGFsbG93IHRlc3RpbmcgZm9yIHRoZSBTb3V0aHdhcmsgdmVyc3VzIExhbWJldGggZWZmZWN0IGluIGEgcXVhc2ktcmFuZG9taXplZCB0cmlhbCBmcmFtZXdvcmsgYXQgYSBzb21ld2hhdCBtb3JlIGFnZ3JlZ2F0ZWQgbGV2ZWwgdGhhbiB0aGUgc3ViLWRpc3RyaWN0IGRhdGEgYWJvdmUsIGJ1dCBjb3ZlcmluZyB0aGUgZnVsbCAxODU0IGNob2xlcmEgb3V0YnJlYWsgCgoKRm9yIGEgYnJpZWYgaW50cm9kdWN0aW9uIHRvIFNub3cncyB3b3JrLCBzZWU6CgorICoqU25vdydzIG9yaWdpbmFsIDE4NTUgbW9ub2dyYXBoKiogKGl0IGlzIG1hc3RlcmZ1bCk6IFNub3csIEpvaG4uIDE4NTUuICpPbiB0aGUgTW9kZSBvZiBDb21tdW5pY2F0aW9uIG9mIENob2xlcmEqLiAybmQgZWQuIExvbmRvbjogSm9obiBDaHVyY2hpbGwuIGh0dHA6Ly9hcmNoaXZlLm9yZy9kZXRhaWxzL2IyODk4NTI2Ni4KKyAqKlRoZSBiZXN0IHBvcHVsYXIgZXhwb3NpdGlvbiBJIGhhdmUgZm91bmQqKjogSm9obnNvbiwgU3RldmVuLiAyMDA3LiAqVGhlIEdob3N0IE1hcDogVGhlIFN0b3J5IG9mIExvbmRvbuKAmXMgTW9zdCBUZXJyaWZ5aW5nIEVwaWRlbWljLS1hbmQgSG93IEl0IENoYW5nZWQgU2NpZW5jZSwgQ2l0aWVzLCBhbmQgdGhlIE1vZGVybiBXb3JsZCouIFJlcHJpbnQgZWRpdGlvbi4gTmV3IFlvcms6IFJpdmVyaGVhZCBCb29rcy4KKyAqKkFub3RoZXIgZ29vZCBwb3B1bGFyIHZlcnNpb24qKjogSGVtcGVsLCBTYW5kcmEuIDIwMDcuICpUaGUgU3RyYW5nZSBDYXNlIG9mIHRoZSBCcm9hZCBTdHJlZXQgUHVtcDogSm9obiBTbm93IGFuZCB0aGUgTXlzdGVyeSBvZiBDaG9sZXJhKi4gRmlyc3QgZWRpdGlvbi4gQmVya2VsZXk6IFVuaXZlcnNpdHkgb2YgQ2FsaWZvcm5pYSBQcmVzcy4KKyAqKlR1ZnRlJ3MgY2xhc3NpYyBkaXNjdXNzaW9uIG9mIFNub3cncyBtYXBwaW5nKiogKGEgdG9waWMgSSBkb24ndCBjb3ZlciBoZXJlKTogVHVmdGUsIEVkd2FyZCBSLiAxOTk3LiAqVmlzdWFsIEV4cGxhbmF0aW9uczogSW1hZ2VzIGFuZCBRdWFudGl0aWVzLCBFdmlkZW5jZSBhbmQgTmFycmF0aXZlKi4gMXN0IGVkaXRpb24uIEdyYXBoaWNzIFByZXNzLgorICoqQmlvZ3JhcGh5Kio6IFZpbnRlbi1Kb2hhbnNlbiwgUGV0ZXIsIEhvd2FyZCBCcm9keSwgTmlnZWwgUGFuZXRoLCBTdGVwaGVuIFJhY2htYW4sIGFuZCBNaWNoYWVsIFJ1c3NlbGwgUmlwLiAyMDAzLiAqQ2hvbGVyYSwgQ2hsb3JvZm9ybSBhbmQgdGhlIFNjaWVuY2Ugb2YgTWVkaWNpbmU6IEEgTGlmZSBvZiBKb2huIFNub3cqLiBPeGZvcmQ7IE5ldyBZb3JrOiBPeGZvcmQgVW5pdmVyc2l0eSBQcmVzcy4gTGlua2VkIG9uLWxpbmUgcmVzb3VyY2VzIGh0dHBzOi8vam9obnNub3cubWF0cml4Lm1zdS5lZHUvc25vd3dvcmtzLnBocAoKCgoKVGhpcyBpcyBhbiBbUiBNYXJrZG93bl0oaHR0cDovL3JtYXJrZG93bi5yc3R1ZGlvLmNvbSkgTm90ZWJvb2suIFdoZW4geW91IGV4ZWN1dGUgY29kZSB3aXRoaW4gdGhlIG5vdGVib29rLCB0aGUgcmVzdWx0cyBhcHBlYXIgYmVuZWF0aCB0aGUgY29kZS4gVGhlIHJlc3VsdHMgYXJlIGFsc28gc2F2ZWQgaW4gYSBzZWxmLWNvbnRhaW5lZCBodG1sIGRvY3VtZW50IHdpdGggdGhlIHN1ZmZpeCAqLm5iLmh0bWwqLiBJZiB5b3Ugd2FudCBwdXJlIHIgY29kZSAoZm9yIGV4YW1wbGUgdG8gcnVuIG91dHNpZGUgUlN0dWRpbykgeW91IGNhbiBlYXNpbHkgZXh0cmFjdCBjb2RlIHdpdGggdGhlIGNvbW1hbmQgKmtuaXQoJ25vdGVib29rLlJtZCcsdGFuZ2xlPVRSVUUpKiB3aGljaCB3aWxsIHNhdmUgYSBmaWxlICdub3RlYm9vay5SJyB1bmRlciB5b3VyIHdvcmtpbmcgZGlyZWN0b3J5LgoKVHJ5IGV4ZWN1dGluZyB0aGUgY2h1bmsgYmVsb3cgYnkgY2xpY2tpbmcgdGhlICpSdW4qIGJ1dHRvbiB3aXRoaW4gdGhlIGNodW5rIG9yIGJ5IHBsYWNpbmcgeW91ciBjdXJzb3IgaW5zaWRlIGl0IGFuZCBwcmVzc2luZyAqQ21kK1NoaWZ0K0VudGVyKi4gCgpgYGBgYGB7ciBtZXNzYWdlPUZBTFNFLCByZXN1bHRzPSdoaWRlJ30KIyBDb3B5cmlnaHQgKGMpIDIwMTksIFRob21hcyBDb2xlbWFuCiMKIyAgLS0tLS0tLSAgTGljZW5zZWQgdW5kZXIgQlNEIDItQ2xhdXNlICJTaW1wbGlmaWVkIiBMaWNlbnNlICAtLS0tLS0tCiMKIyBSZXN1bHRzIGFuZCBkaXNjdXNzaW9uIGluICJDYXVzYWxpdHkgaW4gdGhlIFRpbWUgb2YgQ2hvbGVyYTogSm9obiBTbm93IGFzIGEgUHJvdG90eXBlIAojIGZvciBDYXVzYWwgSW5mZXJlbmNlIChXb3JraW5nIFBhcGVyKSIgYXZhaWxhYmxlIGF0IFNTUk46IGh0dHBzOi8vcGFwZXJzLnNzcm4uY29tL2Fic3RyYWN0PTMyNjIyMzQKCnJtKGxpc3Q9bHMoKSkgICAgIyBzdGFydHMgYSBmcmVzaCB3b3Jrc3BhY2UKIwpsaWJyYXJ5KGtuaXRyKQpvcHRpb25zKHNjaXBlbj01KQojIFRoZSBmb2xsb3dpbmcgbGlicmFyaWVzIGFyZSB1c2VkIGZvciB0aGUgTmVnYXRpdmUgQmlub21pYWwgcmVncmVzc2lvbiBhbmQgdGhlIHJvYnVzdCBzdGFuZGFyZCBlcnJvciBhbmFseXNpcwojaW5zdGFsbC5wYWNrYWdlcygic2FuZHdpY2giKQojaW5zdGFsbC5wYWNrYWdlcygibG10ZXN0IikKbGlicmFyeSgiTUFTUyIpCmxpYnJhcnkoInNhbmR3aWNoIikgCmxpYnJhcnkoImxtdGVzdCIpIAoKIyBSZWFkIGluIHRoZSBkYXRhIGZyb20gU25vdyAxODU1ICJPbiB0aGUgbW9kZSBvZiBjb21tdW5pY2F0aW9uIG9mIGNob2xlcmEiCnRhYmxldmlpIDwtIHJlYWQuY3N2KGZpbGU9IlNub3cxODU1X1RhYmxlVklJLmNzdiIsIGhlYWRlcj1UUlVFLCBzZXA9IiwiLCBza2lwPTUsY29tbWVudC5jaGFyPSIjIikKdGFibGV2aWlpIDwtIHJlYWQuY3N2KGZpbGU9IlNub3cxODU1X1RhYmxlVklJSS5jc3YiLCBoZWFkZXI9VFJVRSwgc2VwPSIsIiwgc2tpcD01LGNvbW1lbnQuY2hhcj0iIyIpCgojIFJlYWQgaW4gdGhlIGRhdGEgZnJvbSBKb2huIFNub3cgMTg1NiwgIkNob2xlcmEgYW5kIHRoZSB3YXRlciBzdXBwbHkgaW4gdGhlIHNvdXRoIGRpc3RyaWN0IG9mIExvbmRvbiBpbiAxODU0IiwgCiMgICBUaGVzZSBkYXRhIHdlcmUgY29waWVkIGZyb20gdGhlIDE5MzYgYm9vayAiU25vdyBvbiBjaG9sZXJhLCBiZWluZyBhIHJlcHJpbnQgb2YgdHdvIHBhcGVycyIgZWRpdGVkIGJ5IEZyb3N0CiMgVGFibGUgViBieSBEaXN0cmljdCAoZm9yIHJ1bm5pbmcgUG9pc3NvbiAmIE5lZyBCaW5vbWlhbCBjb3VudCByZWdyZXNzaW9ucykKIyBUYWJsZSBWSSBieSBzdWItZGlzdHJpY3QgKGZvciBydW5uaW5nIEtvY2ggJiBEZW5pa2UncyB0ZXN0cykKCiMgVGFibGUgSSAiU2hvd2luZyB0aGUgcmVzdWx0cyBvZiB0aGUgQXV0aG9yJ3MgcGVyc29uYWwgSW5xdWlyeSBpbnRvIFR3ZW50eS1PbmUgU3ViLURpc3RyaWN0cyIKIyBUYWJsZSBJSSAiU2hvd2luZyB0aGUgcmVzdWx0cyBvZiBJbnF1aXJ5IG1hZGUgYnkgTXIuIFdoaXRpbmcgaW4gRWxldmVuIFN1Yi1EaXN0cmljdHMiCiMgKE15ICJ0YWJsZWlfMTg1NiIgY29tYmluZXMgU25vdydzIFRhYmxlcyBJICYgSUkpCgp0YWJsZWlfMTg1NiA8LSByZWFkLmNzdihmaWxlPSJTbm93MTg1Nl9UYWJsZUkuY3N2IiwKICBoZWFkZXI9VFJVRSwgc2VwPSIsIiwgc2tpcD01LGNvbW1lbnQuY2hhcj0iIyIpCgp0YWJsZVZfMTg1NiA8LSByZWFkLmNzdihmaWxlPSJTbm93MTg1Nl9UYWJsZVYuY3N2IiwKICBoZWFkZXI9VFJVRSwgc2VwPSIsIiwgc2tpcD01LGNvbW1lbnQuY2hhcj0iIyIpCgoKYGBgCgoKQ2FsY3VsYXRlIG1vcnRhbGl0eSByYXRlcyBmb3IgYWxsIHN1Yi1kaXN0cmljdHMKCmBgYHtyfQojIENhbGN1bGF0ZSBtb3J0YWxpdHkgcmF0ZXMgZm9yIGFsbCBzdWItZGlzdHJpY3RzCnRhYmxlaV8xODU2JHJhdGVTb3V0aHdhcmsgPC0gMTAwMDAgKiB0YWJsZWlfMTg1NiRkZWF0aHNTb3V0aHdhcmsgLyB0YWJsZWlfMTg1NiRzb3V0aHdhcmtfcG9wCnRhYmxlaV8xODU2JHJhdGVMYW1iZXRoIDwtIDEwMDAwICogdGFibGVpXzE4NTYkZGVhdGhzTGFtYmV0aCAvIHRhYmxlaV8xODU2JGxhbWJldGhfcG9wCnRhYmxlaV8xODU2JHJhdGVib3RoIDwtIDEwMDAwICogKHRhYmxlaV8xODU2JGRlYXRoc1NvdXRod2FyayArIHRhYmxlaV8xODU2JGRlYXRoc0xhbWJldGgpIC8gCiAgICAgKHRhYmxlaV8xODU2JHNvdXRod2Fya19wb3AgKyB0YWJsZWlfMTg1NiRsYW1iZXRoX3BvcCkKdGFibGVpXzE4NTYkcmF0ZW92ZXJhbGwgPC0gMTAwMDAgKiB0YWJsZWlfMTg1NiRkZWF0aHNPdmVyYWxsIC8gdGFibGVpXzE4NTYkcG9wMTg1MQoKYGBgCgoKCiMjI0NvdW50IFJlZ3Jlc3Npb25zIGZvciBTbm93IDE4NTUgVGFibGUgVklJSSAoZmlyc3QgNyBzZWVrcywgYnkgc3ViLWRpc3RyaWN0KQoKCiMjIyNQcmVwYXJlIERhdGEKClRvIHJ1biB0aGUgcmVncmVzc2lvbnMgd2UgbmVlZCB0byBzdGFjayB0aGUgZGF0YSwgZG8gc29tZSBtaW5vciBkYXRhIGNsZWFuLXVwIChjb252ZXJ0IHNvbWUgbm9uLW51bWVyaWNzIHRvIG51bWVyaWNzKSwgYW5kIG1ha2UgYW4gaW5kaWNhdG9yIHZhcmlhYmxlIGZvciBzdXBwbGllciAoSSB1c2UgInhMYW1iZXRoIiBzbyB0aGF0ICJTb3V0aHdhcmsiIGlzIHRoZSBleGNsdWRlZCBjYXRlZ29yeSAtIFIgZXhjbHVkZXMgdGhlIGZpcnN0IGNhdGVnb3J5IGJ5IGFscGhhYmV0aWMgc29ydCkuCgoKYGBge3J9CiMgUHJlcGFyZSBkYXRhIGZvciB0aGUgc3ViLWRpc3RyaWN0cyBvZiB0aGUgam9pbnRseS1zdXBwbGllZCAibmV4dCAxNiIgc3ViLWRpc3RyaWN0cwojIFRoZXJlIGlzIGRhdGEgZm9yIFNvdXRod2Fyay1zdXBwbGllZCBjdXN0b21lcnMgYW5kIExhbWJldGgtc3VwcGxpZWQgY3VzdG9tZXJzIAojIHNvIHRoZXJlIGFyZSB0d28gc2V0cyBvZiBvYnNlcnZhdGlvbnMgZm9yIGVhY2ggc3ViLWRpc3RyaWN0CngxIDwtIHN1YnNldCh0YWJsZWlfMTg1NixzdXBwbGllciA9PSAiU291dGh3YXJrVmF1eGhhbGxfTGFtYmV0aCIpCnhTb3V0aHdhcmsgPC0geDFbYygic3ViRGlzdHJpY3QiLCJkaXN0cmljdCIsInN1cHBsaWVyIildCnhTb3V0aHdhcmskZGVhdGhzIDwtIHgxJGRlYXRoc1NvdXRod2Fyawp4U291dGh3YXJrJHBvcHVsYXRpb24gPC0geDEkc291dGh3YXJrX3BvcAp4U291dGh3YXJrJHJhdGUgPC0gMTAwMDAgKiB4U291dGh3YXJrJGRlYXRocyAvIHhTb3V0aHdhcmskcG9wdWxhdGlvbgp4U291dGh3YXJrJHNlcSA8LSBjKHNlcSgxMywxMitsZW5ndGgoeFNvdXRod2FyayRkZWF0aHMpKSkKeFNvdXRod2FyayRzdXBwbGllciA8LSAiU291dGh3YXJrIgojIHRoZSAiYXMuY2hhcmFjdGVyIC4uLiIgaXMgbmVjZXNzYXJ5IGJlY2F1c2UgcG9wX3Blcl9ob3VzZSBpcyBzdG9yZWQgYXMgYSBmYWN0b3IsIG5vdCBhIG51bWVyaWMKeFNvdXRod2FyayRwb3BfcGVyX2hvdXNlIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHgxJHBvcF9wZXJfaG91c2UpKSAgCiN4U291dGh3YXJrJGR1bTE4NTQgPC0gMAp4TGFtYmV0aCA8LSB4MVtjKCJzdWJEaXN0cmljdCIsImRpc3RyaWN0Iiwic3VwcGxpZXIiKV0KeExhbWJldGgkZGVhdGhzIDwtIHgxJGRlYXRoc0xhbWJldGgKeExhbWJldGgkcG9wdWxhdGlvbiA8LSB4MSRsYW1iZXRoX3BvcAp4TGFtYmV0aCRyYXRlIDwtIDEwMDAwICogeExhbWJldGgkZGVhdGhzIC8geExhbWJldGgkcG9wdWxhdGlvbgp4TGFtYmV0aCRzZXEgPC0gYyhzZXEoMTMsMTIrbGVuZ3RoKHhMYW1iZXRoJGRlYXRocykpKQp4TGFtYmV0aCRzdXBwbGllciA8LSAieExhbWJldGgiCiMgdGhlICJhcy5jaGFyYWN0ZXIgLi4uIiBpcyBuZWNlc3NhcnkgYmVjYXVzZSBwb3BfcGVyX2hvdXNlIGlzIHN0b3JlZCBhcyBhIGZhY3Rvciwgbm90IGEgbnVtZXJpYwp4TGFtYmV0aCRwb3BfcGVyX2hvdXNlIDwtIGFzLm51bWVyaWMoYXMuY2hhcmFjdGVyKHgxJHBvcF9wZXJfaG91c2UpKQoKCnJlZ2RhdGExODU1VklJam9pbnQgPC0gcmJpbmQoeFNvdXRod2Fyayx4TGFtYmV0aCkKCiMgUHJlcGFyZSBkYXRhIGZvciB0aGUgc3ViLWRpc3RyaWN0cyBvZiB0aGUgU291dGh3YXJrLXN1cHBsaWVkICJmaXJzdCAxMiIgc3ViLWRpc3RyaWN0cwojIFRoZXJlIGlzIGRhdGEgb25seSBmb3IgU291dGh3YXJrLXN1cHBsaWVkIGN1c3RvbWVycyBjdXN0b21lcnMgKGFsdGhvdWdoIHRoZSBwb3B1bGF0aW9uCiMgbnVtYmVycyBxdW90ZWQgaW4gU25vdyAxODU2IFRhYmxlcyBJICYgSUkgc2hvdyBwb3B1bGF0aW9uIGZvciBMYW1iZXRoIGN1c3RvbWVycyBmb3Igc29tZQojIG9mIHRoZXNlIHN1Yi1kaXN0cmljdHMsIGFzIFNub3cgcG9pbnRzIG91dCB0aGlzIGlzIGluY29ycmVjdC4gVGh1cyBJIGFtIGltcG9zaW5nIGFzc3VtcHRpb24KIyB0aGF0IHBvcHVsYXRpb24gYW5kIGNvdW50cyBmb3IgTGFtYmV0aC1zdXBwbGllZCBjdXN0b21lcnMgZm9yIHRoZXNlIHN1Yi1kaXN0cmljdHMgaXMgemVybykKIyBzbyB0aGVyZSBhcmUgdHdvIHNldHMgb2Ygb2JzZXJ2YXRpb25zIGZvciBlYWNoIHN1Yi1kaXN0cmljdAp4MSA8LSBzdWJzZXQodGFibGVpXzE4NTYsc3VwcGxpZXIgPT0gIlNvdXRod2Fya1ZhdXhoYWxsIikKeFNvdXRod2Fya29ubHkgPC0geDFbYygic3ViRGlzdHJpY3QiLCJkaXN0cmljdCIsInN1cHBsaWVyIildCnhTb3V0aHdhcmtvbmx5JGRlYXRocyA8LSB4MSRkZWF0aHNTb3V0aHdhcmsKeFNvdXRod2Fya29ubHkkcG9wdWxhdGlvbiA8LSB4MSRzb3V0aHdhcmtfcG9wCnhTb3V0aHdhcmtvbmx5JHJhdGUgPC0gMTAwMDAgKiB4U291dGh3YXJrb25seSRkZWF0aHMgLyB4U291dGh3YXJrb25seSRwb3B1bGF0aW9uCnhTb3V0aHdhcmtvbmx5JHNlcSA8LSBjKHNlcSgxLGxlbmd0aCh4U291dGh3YXJrb25seSRkZWF0aHMpKSkKeFNvdXRod2Fya29ubHkkc3VwcGxpZXIgPC0gIlNvdXRod2FyayIKIyB0aGUgImFzLmNoYXJhY3RlciAuLi4iIGlzIG5lY2Vzc2FyeSBiZWNhdXNlIHBvcF9wZXJfaG91c2UgaXMgc3RvcmVkIGFzIGEgZmFjdG9yLCBub3QgYSBudW1lcmljCnhTb3V0aHdhcmtvbmx5JHBvcF9wZXJfaG91c2UgPC0gYXMubnVtZXJpYyhhcy5jaGFyYWN0ZXIoeDEkcG9wX3Blcl9ob3VzZSkpICAKI3hTb3V0aHdhcmskZHVtMTg1NCA8LSAwCgpyZWdkYXRhMTg1NVZJSWJvdGggPC0gcmJpbmQoeFNvdXRod2Fya29ubHkseFNvdXRod2Fyayx4TGFtYmV0aCkKCgpgYGAKCgoKCiMjIyNQb2lzc29uIFJlZ3Jlc3Npb25zCgpUaGlzIGNvZGUgY2h1bmsgcnVucyB0aGUgUG9pc3NvbiByZWdyZXNzaW9ucywgYnV0IEkgYW0gbm90IHByaW50aW5nIHRoZW0gb3V0IGhlcmUuCgpgYGB7cn0KIyBQb2lzc29uIHdpdGggc2FtZSByYXRlIGZvciBhbGwgc3ViLWRpc3RyaWN0cyAobm8gc3ViLWRpc3RyaWN0IGZpeGVkIGVmZmVjdHMpCnBvaXMxX1RhYmxlVklJSSA8LSBnbG0oZGVhdGhzIH4gc3VwcGxpZXIgCgkrIG9mZnNldChsb2cocG9wdWxhdGlvbikpLCBmYW1pbHk9cG9pc3NvbiwgZGF0YSA9IHJlZ2RhdGExODU1VklJam9pbnQpCnBvaXMxX1RhYmxlVklJSXJvYnVzdHNlIDwtIGNvZWZ0ZXN0KHBvaXMxX1RhYmxlVklJSSwgdmNvdiA9IHZjb3ZIQyhwb2lzMV9UYWJsZVZJSUkpKQojc3VtbWFyeShwb2lzMV9UYWJsZVZJSUkpKQojcHJpbnQocG9pczFfVGFibGVWSUlJcm9idXN0c2UpCgojIFBvaXNzb24gd2l0aCBwb3B1bGF0aW9uIChob3VzaW5nKSBkZW5zaXR5CnBvaXMxcG9wX1RhYmxlVklJSSA8LSBnbG0oZGVhdGhzIH4gc3VwcGxpZXIgKyBwb3BfcGVyX2hvdXNlIAoJKyBvZmZzZXQobG9nKHBvcHVsYXRpb24pKSwgZmFtaWx5PXBvaXNzb24sIGRhdGEgPSByZWdkYXRhMTg1NVZJSWpvaW50KQpwb2lzMXBvcF9UYWJsZVZJSUlyb2J1c3RzZSA8LSBjb2VmdGVzdChwb2lzMXBvcF9UYWJsZVZJSUksIHZjb3YgPSB2Y292SEMocG9pczFwb3BfVGFibGVWSUlJKSkKI3N1bW1hcnkocG9pczFwb3BfVGFibGVWSUlJKSkKI3ByaW50KHBvaXMxcG9wX1RhYmxlVklJSXJvYnVzdHNlKQoKIyBQb2lzc29uIHdpdGggZGlmZmVyZW50IHJhdGVzIGJ5IHN1Yi1kaXN0cmljdCAoZml4ZWQgZWZmZWN0cykKcG9pczJfVGFibGVWSUlJIDwtIGdsbShkZWF0aHMgfiBzdXBwbGllciArIHN1YkRpc3RyaWN0CgkrIG9mZnNldChsb2cocG9wdWxhdGlvbikpLCBmYW1pbHk9cG9pc3NvbiwgZGF0YSA9IHJlZ2RhdGExODU1VklJam9pbnQpCnBvaXMyX1RhYmxlVklJSXJvYnVzdHNlIDwtIGNvZWZ0ZXN0KHBvaXMyX1RhYmxlVklJSSwgdmNvdiA9IHZjb3ZIQyhwb2lzMl9UYWJsZVZJSUkpKQojc3VtbWFyeShwb2lzMl9UYWJsZVZJSUkpKQojcHJpbnQocG9pczJfVGFibGVWSUlJcm9idXN0c2UpCgojIFF1YXNpLVBvaXNzb24sIGFsbG93aW5nIGRpc3BlcnNpb24gdG8gYmUgYSBmcmVlIHBhcmFtZXRlcgpwb2lzUXVhc2kgPC0gZ2xtKGRlYXRocyB+IHN1cHBsaWVyIAoJKyBvZmZzZXQobG9nKHBvcHVsYXRpb24pKSwgZmFtaWx5PXF1YXNpcG9pc3NvbiwgZGF0YSA9IHJlZ2RhdGExODU1VklJam9pbnQpCnBvaXNRdWFzaXJvYnVzdHNlIDwtIGNvZWZ0ZXN0KHBvaXNRdWFzaSwgdmNvdiA9IHZjb3ZIQyhwb2lzUXVhc2kpKQojc3VtbWFyeShwb2lzUXVhc2kpKQoKCgpgYGAKCkFzIHdpdGggb3RoZXIgcmVncmVzc2lvbnMgd2l0aCBjaG9sZXJhIG1vcnRhbGl0eSBkYXRhLCB0aGVzZSBQb2lzc29uIHJlZ3Jlc3Npb25zIGhhdmUgdHJvdWJsZSB3aXRoICJvdmVyZGlzcGVyc2lvbiIgLSBtb3JlIHZhcmlhdGlvbiBhY3Jvc3Mgc3ViLWRpc3RyaWN0cyB0aGFuIGNhbiBiZSBhY2NvdW50ZWQgZm9yIHNpbXBseSBieSB2YXJpYXRpb24gaW4gUG9pc3NvbiBjb3VudHMuIEkgZGlzY3VzcyBhbmQgc3VtbWFyaXplIHRoZSByZXN1bHRzIGJlbG93LiAKCgoKIyMjI05lZ2F0aXZlIEJpbm9taWFsIFJlZ3Jlc3Npb25zCgpUaGUgZm9sbG93aW5nIGNvZGUgY2h1bmsgcnVucyBOZWdhdGl2ZSBCaW5vbWlhbCByZWdyZXNzaW9ucywgYm90aCB3aXRoIGFuZCB3aXRob3V0IHBvcHVsYXRpb24gZGVuc2l0eS4gSW5jbHVkaW5nIHBvcHVsYXRpb24gZGVuc2l0eSAoaG91c2luZyBkZW5zaXR5KSB0ZXN0cyB3aGV0aGVyIGNyb3dkaW5nIGlzIGFuIGltcG9ydGFudCBjb250cmlidXRpbmcgZmFjdG9yIHRvIGNob2xlcmEgbW9ydGFsaXR5LCBhbmQgd2hldGhlciBkaWZmZXJlbmNlIGluIHdhdGVyIHN1cHBseSBpcyBzdGlsbCBpbXBvcnRhbnQgd2hlbiB3ZSBpbmNsdWRlIGRlbnNpdHkuIFRoZSBjb25jbHVzaW9uLCBkaXNjdXNzZWQgbW9yZSBiZWxvdywgaXMgdGhhdCBwb3B1bGF0aW9uIGRlbnNpdHkgcmVhbGx5IGRvZXMgbm90IG1hdHRlci4gCgpgYGB7cn0KIyBOZWdhdGl2ZSBCaW5vbWlhbCAKbmIxX1RhYmxlVklJSSA8LSBnbG0ubmIoZGVhdGhzIH4gc3VwcGxpZXIgKyBvZmZzZXQobG9nKHBvcHVsYXRpb24pKSwgZGF0YSA9IHJlZ2RhdGExODU1VklJam9pbnQpCm5iMV9UYWJsZVZJSUlyb2J1c3RzZSA8LSBjb2VmdGVzdChuYjFfVGFibGVWSUlJLCB2Y292ID0gdmNvdkhDKG5iMV9UYWJsZVZJSUkpKQojc3VtbWFyeShuYjFfVGFibGVWSUlJKSkKI3ByaW50KG5iMV9UYWJsZVZJSUlyb2J1c3RzZSkKCgojIE5lZ2F0aXZlIEJpbm9taWFsIHdpdGggZGlzdHJpY3QgZml4ZWQgZWZmZWN0cwojIERvZXNuJ3QgY29udmVyZ2Ugc28gY29tbWVudCBvdXQgCiNuYjJfVGFibGVWSUlJIDwtIGdsbS5uYihkZWF0aHMgfiBzdXBwbGllciArIHN1YkRpc3RyaWN0CiMJKyBvZmZzZXQobG9nKHBvcHVsYXRpb24pKSwgZGF0YSA9IHJlZ2RhdGExODU1VklJam9pbnQpCiNuYjJfVGFibGVWSUlJcm9idXN0c2UgPC0gY29lZnRlc3QobmIyX1RhYmxlVklJSSwgdmNvdiA9IHZjb3ZIQyhuYjJfVGFibGVWSUlJKSkKI3N1bW1hcnkobmIyX1RhYmxlVklJSSkpCiNwcmludChuYjJfVGFibGVWSUlJcm9idXN0c2UpCgojIFRoZSBmb2xsb3dpbmcgZG9lcyByb2J1c3Qgc3RhbmRhcmQgZXJyb3JzLiBJIGNyaWJiZWQgdGhpcyBmcm9tCiMgIFN0YXJ0OiAKIyAgaHR0cHM6Ly9zdGF0LmV0aHouY2gvcGlwZXJtYWlsL3ItaGVscC8yMDA4LU1heS8xNjE1OTEuaHRtbAojVGhlbiBjbGljayBvbiAiTmV4dCBtZXNzYWdlOiIgZm9yIHRoZSBzZWNvbmQuIFVuZm9ydHVuYXRlbHksIAojYXQgdGhhdCBwb2ludCB0aGUgdGhyZWFkIGJyb2tlIChQYXVsIG5leHQgcmVzcG9uZGVkIHRvIHRoZSBsaXN0IAojYXMgYSByZXBseSB0byBhbiBvZmYtbGlzdCBtZXNzYWdlIEkgc2VudCBoaW0pLiBTbyB0byBjb250aW51ZSwgCiNuZXh0IHRha2UgQWNoaW0ncyBVUkwgYWJvdmU6IAojICBodHRwczovL3N0YXQuZXRoei5jaC9waXBlcm1haWwvci1oZWxwLzIwMDgtTWF5LzE2MTY0MC5odG1sCiNhbmQgdGhlcmVhZnRlciBjb250aW51ZSB0byBjbGljayBvbiAiTmV4dCBtZXNzYWdlOiIgdW50aWwgdGhlIAojdGhyZWFkIHJ1bnMgb3V0LiAKCiMgY2YgaHR0cHM6Ly9zdGF0cy5zdGFja2V4Y2hhbmdlLmNvbS9xdWVzdGlvbnMvMTE3MDUyL3JlcGxpY2F0aW5nLXN0YXRhcy1yb2J1c3Qtb3B0aW9uLWluLXIKIyBTVEFUQSBzZWVtcyB0byB1c2UgSEMxIGZvciByb2J1c3QgQlVUIHdpdGggbi0xIGluc3RlYWQgb2Ygbi1rIChzZWUgInNhbmR3aWNoLnBkZiIgYW5kIAojCWh0dHBzOi8vc3RhdHMuc3RhY2tleGNoYW5nZS5jb20vcXVlc3Rpb25zLzg5OTk5L2hvdy10by1yZXBsaWNhdGUtc3RhdGFzLXJvYnVzdC1iaW5vbWlhbC1nbG0tZm9yLXByb3BvcnRpb24tZGF0YS1pbi1yKQoKIyBOZWdhdGl2ZSBCaW5vbWlhbCByZWdyZXNzaW9uIHdpdGggcG9wdWxhdGlvbiBkZW5zaXR5IGFzIGEgcmVncmVzc29yCiMgSWRlYSBpcyB0byB0ZXN0IFNub3cncyAxODU2IGFzc2VydGlvbiB0aGF0IGRlbnNpdHkgaGFzIG5vIGVmZmVjdCBhZnRlcgojIHRha2luZyBpbnRvIGFjY291bnQgdGhlIHdhdGVyIHN1cHBsaWVyIChTb3V0aHdhcmsgdnMgTGFtYmV0aCkKIyBSZXN1bHRzIHNlZW0gdG8gc2hvdyB0aGF0IHBvcCBkZW5zaXR5IGlzIG5vdCBzaWduaWZpY2FudC4KIyBSZW1lbWJlciAtIFRvIGdldCAiTGFtYmV0aCBlZmZlY3QiIG5lZWQgdG8gdGFrZSBjb25zdCArIGNvZWZmKGRlbnNpdHkpKmF2ZyhkZW5zaXR5KQpuYjFwb3BfVGFibGVWSUlJIDwtIGdsbS5uYihkZWF0aHMgfiBzdXBwbGllciArIHBvcF9wZXJfaG91c2UgCgkrIG9mZnNldChsb2cocG9wdWxhdGlvbikpLCBkYXRhID0gcmVnZGF0YTE4NTVWSUlqb2ludCkKbmIxcG9wX1RhYmxlVklJSXJvYnVzdHNlIDwtIGNvZWZ0ZXN0KG5iMXBvcF9UYWJsZVZJSUksIHZjb3YgPSB2Y292SEMobmIxcG9wX1RhYmxlVklJSSkpCiNzdW1tYXJ5KG5iMXBvcF9UYWJsZVZJSUkpKQojcHJpbnQobmIxcG9wX1RhYmxlVklJSXJvYnVzdHNlKQoKCm5iMXBvcF9UYWJsZVZJSUlib3RoIDwtIGdsbS5uYihkZWF0aHMgfiBzdXBwbGllciArIHBvcF9wZXJfaG91c2UgCgkrIG9mZnNldChsb2cocG9wdWxhdGlvbikpLCBkYXRhID0gcmVnZGF0YTE4NTVWSUlib3RoKQpuYjFwb3BfVGFibGVWSUlJYm90aHJvYnVzdHNlIDwtIGNvZWZ0ZXN0KG5iMXBvcF9UYWJsZVZJSUlib3RoLCB2Y292ID0gdmNvdkhDKG5iMXBvcF9UYWJsZVZJSUlib3RoKSkKI3N1bW1hcnkobmIxcG9wX1RhYmxlVklJSWJvdGgpKQojcHJpbnQobmIxcG9wX1RhYmxlVklJSWJvdGhyb2J1c3RzZSkKCgoKYGBgCgojIyMjU3VtbWFyeSBUYWJsZQoKVGhlIGZvbGxvd2luZyBjb2RlIGNodW5rIGNyZWF0ZXMgYSBsYXJnZSB0YWJsZSB3aXRoIHN1bW1hcnkgc3RhdGlzdGljcyBmcm9tIGEgdmFyaWV0eSBvZiByZWdyZXNzaW9ucyBmb3IgdGhlIDE4NTUgVGFibGUgVklJSSBkYXRhOgoKKyBQb2lzc29uOiBiYXNpYzsgaW5jbHVkaW5nIHBvcHVsYXRpb24gKGhvdXNpbmcpIGRlbnNpdHk7IEZpeGVkIGVmZmVjdHM7IFF1YXNpLVBvaXNzb24gKGFsbG93aW5nIGZvciBvdmVyLWRpc3BlcnNpb24pCisgTmVnYXRpdmUgQmlub21pYWw6IGJhc2ljOyBpbmNsdWRpbmcgcG9wdWxhdGlvbiAoaG91c2luZykgZGVuc2l0eQoKYGBge3J9CiMgQ3JlYXRlIHRhYmxlIHdpdGggcmVncmVzc2lvbiByZXN1bHRzIApyZWd0YWJsZTE4NTVUYWJsZVZJSUkgPC0gbWF0cml4KDAsbnJvdz0xNixuY29sPTgpCmNvbG5hbWVzKHJlZ3RhYmxlMTg1NVRhYmxlVklJSSkgPC0gYygiUG9pc3MiLCJQb2lzcyBwb3AiLCJQb2lzcyBGRSIsIlBvaXNzIFF1YXNpIiwiTkIiLCJOQiBwb3AiLAoJIk5CIEZFIiwiTkIgYWxsIHJlZyBwb3AiKQpyb3duYW1lcyhyZWd0YWJsZTE4NTVUYWJsZVZJSUkpIDwtIGMoIkxhbWJldGggZWZmZWN0IiwiU0UiLCJ6LXZhbHVlIiwicCB2YWx1ZSIsInJvYnVzdCBTRSIsInogdmFsdWUiLAoJInJhdGlvIGVmZmVjdCIsCgkidGhldGEiLCJzdWItZGlzdCBGRSIsInBvcCBkZW4iLAoJIlNFIiwiei12YWx1ZSIsInJlc2lkIGRldiIsICJwLXZhbHVlIiwiU291dGh3YXJrIFByZWQgTW9ydCIsIkxhbWJldGggUHJlZCBNb3J0IikKIyBQb3B1bGF0ZSB0aGUgdGFibGUgZnJvbSB0aGUgcmVncmVzc2lvbnMKIyBjYWxjdWxhdGUgcG9wdWxhdGlvbiBmb3IgU291dGh3YXJrICYgTGFtYmV0aAp4cyA8LSBzdW0ocmVnZGF0YTE4NTVWSUlqb2ludCRwb3B1bGF0aW9uWzE6MTZdKQp4bCA8LSBzdW0ocmVnZGF0YTE4NTVWSUlqb2ludCRwb3B1bGF0aW9uWzE3OjMyXSkKIyBQb2lzc29uIG5vIHN1Yi1kaXN0cmljdCBGRXMgCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVtjKDEsMiwzLDQpLDFdIDwtIHN1bW1hcnkocG9pczFfVGFibGVWSUlJKSRjb2VmZmljaWVudHNbMixjKDEsMiwzLDQpXQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbYyg1LDYpLDFdIDwtIHBvaXMxX1RhYmxlVklJSXJvYnVzdHNlWzIsYygyLDMpXQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbNywxXSA8LSBleHAoLXJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxLDFdKQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbMTMsMV0gPC0gc3VtbWFyeShwb2lzMV9UYWJsZVZJSUkpJGRldmlhbmNlCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxNCwxXSA8LSAxIC0gcGNoaXNxKHBvaXMxX1RhYmxlVklJSSRkZXZpYW5jZSxwb2lzMV9UYWJsZVZJSUkkZGYucmVzaWR1YWwpCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxNSwxXSA8LSAxMDAwMCAqIHN1bShwb2lzMV9UYWJsZVZJSUkkZml0dGVkLnZhbHVlc1sxOjE2XSkgLyB4cwpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbMTYsMV0gPC0gMTAwMDAgKiBzdW0ocG9pczFfVGFibGVWSUlJJGZpdHRlZC52YWx1ZXNbMTc6MzJdKSAvIHhsCiMgUG9pc3NvbiBwb3B1bGF0aW9uIGRlbnNpdHkKcmVndGFibGUxODU1VGFibGVWSUlJW2MoMSwyLDMsNCksMl0gPC0gc3VtbWFyeShwb2lzMXBvcF9UYWJsZVZJSUkpJGNvZWZmaWNpZW50c1syLGMoMSwyLDMsNCldCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVtjKDUsNiksMl0gPC0gcG9pczFwb3BfVGFibGVWSUlJcm9idXN0c2VbMixjKDIsMyldCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVs3LDJdIDwtIGV4cCgtcmVndGFibGUxODU1VGFibGVWSUlJWzEsMl0pCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVtjKDEwLDExLDEyKSwyXSA8LSBzdW1tYXJ5KHBvaXMxcG9wX1RhYmxlVklJSSkkY29lZmZpY2llbnRzWzMsYygxLDIsMyldCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxMywyXSA8LSBzdW1tYXJ5KHBvaXMxcG9wX1RhYmxlVklJSSkkZGV2aWFuY2UKcmVndGFibGUxODU1VGFibGVWSUlJWzE0LDJdIDwtIDEgLSBwY2hpc3EocG9pczFwb3BfVGFibGVWSUlJJGRldmlhbmNlLHBvaXMxcG9wX1RhYmxlVklJSSRkZi5yZXNpZHVhbCkKcmVndGFibGUxODU1VGFibGVWSUlJWzE1LDJdIDwtIDEwMDAwICogc3VtKHBvaXMxcG9wX1RhYmxlVklJSSRmaXR0ZWQudmFsdWVzWzE6MTZdKSAvIHhzCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxNiwyXSA8LSAxMDAwMCAqIHN1bShwb2lzMXBvcF9UYWJsZVZJSUkkZml0dGVkLnZhbHVlc1sxNzozMl0pIC8geGwKIyBQb2lzc29uIHllcyBzdWItZGlzdHJpY3QgRkVzCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVtjKDEsMiwzLDQpLDNdIDwtIHN1bW1hcnkocG9pczJfVGFibGVWSUlJKSRjb2VmZmljaWVudHNbMixjKDEsMiwzLDQpXQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbYyg1LDYpLDNdIDwtIHBvaXMyX1RhYmxlVklJSXJvYnVzdHNlWzIsYygyLDMpXQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbNywzXSA8LSBleHAoLXJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxLDNdKQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbMTMsM10gPC0gc3VtbWFyeShwb2lzMl9UYWJsZVZJSUkpJGRldmlhbmNlCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxNCwzXSA8LSAxIC0gcGNoaXNxKHBvaXMyX1RhYmxlVklJSSRkZXZpYW5jZSxwb2lzMl9UYWJsZVZJSUkkZGYucmVzaWR1YWwpCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxNSwzXSA8LSAxMDAwMCAqIHN1bShwb2lzMl9UYWJsZVZJSUkkZml0dGVkLnZhbHVlc1sxOjE2XSkgLyB4cwpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbMTYsM10gPC0gMTAwMDAgKiBzdW0ocG9pczJfVGFibGVWSUlJJGZpdHRlZC52YWx1ZXNbMTc6MzJdKSAvIHhsCiMgUXVhc2ktUG9pc3NvbiBubyBzdWItZGlzdHJpY3QgRkVzCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVtjKDEsMiwzLDQpLDRdIDwtIHN1bW1hcnkocG9pc1F1YXNpKSRjb2VmZmljaWVudHNbMixjKDEsMiwzLDQpXQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbNyw0XSA8LSBleHAoLXJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxLDRdKQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbMTMsNF0gPC0gc3VtbWFyeShwb2lzUXVhc2kpJGRldmlhbmNlCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxNCw0XSA8LSAxIC0gcGNoaXNxKHBvaXNRdWFzaSRkZXZpYW5jZSxwb2lzUXVhc2kkZGYucmVzaWR1YWwpCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxNSw0XSA8LSAxMDAwMCAqIHN1bShwb2lzUXVhc2kkZml0dGVkLnZhbHVlc1sxOjE2XSkgLyB4cwpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbMTYsNF0gPC0gMTAwMDAgKiBzdW0ocG9pc1F1YXNpJGZpdHRlZC52YWx1ZXNbMTc6MzJdKSAvIHhsCiMgTkIgbm8gc3ViLWRpc3RyaWN0IEZFcwpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbYygxLDIsMyw0KSw1XSA8LSBzdW1tYXJ5KG5iMV9UYWJsZVZJSUkpJGNvZWZmaWNpZW50c1syLGMoMSwyLDMsNCldCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVtjKDUsNiksNV0gPC0gbmIxX1RhYmxlVklJSXJvYnVzdHNlWzIsYygyLDMpXQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbNyw1XSA8LSBleHAoLXJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxLDVdKQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbOCw1XSA8LSBzdW1tYXJ5KG5iMV9UYWJsZVZJSUkpJHRoZXRhCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxMyw1XSA8LSBzdW1tYXJ5KG5iMV9UYWJsZVZJSUkpJGRldmlhbmNlCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxNCw1XSA8LSAxIC0gcGNoaXNxKG5iMV9UYWJsZVZJSUkkZGV2aWFuY2UsbmIxX1RhYmxlVklJSSRkZi5yZXNpZHVhbCkKcmVndGFibGUxODU1VGFibGVWSUlJWzE1LDVdIDwtIDEwMDAwICogc3VtKG5iMV9UYWJsZVZJSUkkZml0dGVkLnZhbHVlc1sxOjE2XSkgLyB4cwpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbMTYsNV0gPC0gMTAwMDAgKiBzdW0obmIxX1RhYmxlVklJSSRmaXR0ZWQudmFsdWVzWzE3OjMyXSkgLyB4bAojIE5CIGluY2x1ZGluZyBwb3B1bGF0aW9uIGRlbnNpdHkKcmVndGFibGUxODU1VGFibGVWSUlJW2MoMSwyLDMsNCksNl0gPC0gc3VtbWFyeShuYjFwb3BfVGFibGVWSUlJKSRjb2VmZmljaWVudHNbMixjKDEsMiwzLDQpXQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbYyg1LDYpLDZdIDwtIG5iMXBvcF9UYWJsZVZJSUlyb2J1c3RzZVsyLGMoMiwzKV0KcmVndGFibGUxODU1VGFibGVWSUlJWzcsNl0gPC0gZXhwKC1yZWd0YWJsZTE4NTVUYWJsZVZJSUlbMSw2XSkKcmVndGFibGUxODU1VGFibGVWSUlJW2MoMTAsMTEsMTIpLDZdIDwtIHN1bW1hcnkobmIxcG9wX1RhYmxlVklJSSkkY29lZmZpY2llbnRzWzMsYygxLDIsMyldCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVs4LDZdIDwtIHN1bW1hcnkobmIxcG9wX1RhYmxlVklJSSkkdGhldGEKcmVndGFibGUxODU1VGFibGVWSUlJWzEzLDZdIDwtIHN1bW1hcnkobmIxcG9wX1RhYmxlVklJSSkkZGV2aWFuY2UKcmVndGFibGUxODU1VGFibGVWSUlJWzE0LDZdIDwtIDEgLSBwY2hpc3EobmIxcG9wX1RhYmxlVklJSSRkZXZpYW5jZSxuYjFwb3BfVGFibGVWSUlJJGRmLnJlc2lkdWFsKQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbMTUsNl0gPC0gMTAwMDAgKiBzdW0obmIxcG9wX1RhYmxlVklJSSRmaXR0ZWQudmFsdWVzWzE6MTZdKSAvIHhzCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxNiw2XSA8LSAxMDAwMCAqIHN1bShuYjFwb3BfVGFibGVWSUlJJGZpdHRlZC52YWx1ZXNbMTc6MzJdKSAvIHhsCiMgTkIgeWVzIHN1Yi1kaXN0cmljdCBGRXMKI3JlZ3RhYmxlMTg1NVRhYmxlVklJSVtjKDEsMiwzLDQpLDddIDwtIHN1bW1hcnkobmIyX1RhYmxlVklJSSkkY29lZmZpY2llbnRzWzIsYygxLDIsMyw0KV0KI3JlZ3RhYmxlMTg1NVRhYmxlVklJSVtjKDUsNiksN10gPC0gbmIyX1RhYmxlVklJSXJvYnVzdHNlWzIsYygyLDMpXQojcmVndGFibGUxODU1VGFibGVWSUlJWzcsN10gPC0gZXhwKC1yZWd0YWJsZTE4NTVUYWJsZVZJSUlbMSw3XSkKI3JlZ3RhYmxlMTg1NVRhYmxlVklJSVs4LDddIDwtIHN1bW1hcnkobmIyX1RhYmxlVklJSSkkdGhldGEKI3JlZ3RhYmxlMTg1NVRhYmxlVklJSVsxMyw3XSA8LSBzdW1tYXJ5KG5iMl9UYWJsZVZJSUkpJGRldmlhbmNlCiNyZWd0YWJsZTE4NTVUYWJsZVZJSUlbMTUsN10gPC0gMTAwMDAgKiBzdW0obmIyX1RhYmxlVklJSSRmaXR0ZWQudmFsdWVzWzE6MTZdKSAvIHhzCiNyZWd0YWJsZTE4NTVUYWJsZVZJSUlbMTYsN10gPC0gMTAwMDAgKiBzdW0obmIyX1RhYmxlVklJSSRmaXR0ZWQudmFsdWVzWzE3OjMyXSkgLyB4bAojIE5CIGluY2x1ZGluZyBwb3B1bGF0aW9uIGRlbnNpdHksIGZvciBhbGwgc3ViLWRpc3RyaWN0CnJlZ3RhYmxlMTg1NVRhYmxlVklJSVtjKDEsMiwzLDQpLDhdIDwtIHN1bW1hcnkobmIxcG9wX1RhYmxlVklJSWJvdGgpJGNvZWZmaWNpZW50c1syLGMoMSwyLDMsNCldCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVtjKDUsNiksOF0gPC0gbmIxcG9wX1RhYmxlVklJSWJvdGhyb2J1c3RzZVsyLGMoMiwzKV0KcmVndGFibGUxODU1VGFibGVWSUlJWzcsOF0gPC0gZXhwKC1yZWd0YWJsZTE4NTVUYWJsZVZJSUlbMSw4XSkKcmVndGFibGUxODU1VGFibGVWSUlJW2MoMTAsMTEsMTIpLDhdIDwtIHN1bW1hcnkobmIxcG9wX1RhYmxlVklJSWJvdGgpJGNvZWZmaWNpZW50c1szLGMoMSwyLDMpXQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbOCw4XSA8LSBzdW1tYXJ5KG5iMXBvcF9UYWJsZVZJSUlib3RoKSR0aGV0YQpyZWd0YWJsZTE4NTVUYWJsZVZJSUlbMTMsOF0gPC0gc3VtbWFyeShuYjFwb3BfVGFibGVWSUlJYm90aCkkZGV2aWFuY2UKcmVndGFibGUxODU1VGFibGVWSUlJWzE0LDhdIDwtIDEgLSBwY2hpc3EobmIxcG9wX1RhYmxlVklJSWJvdGgkZGV2aWFuY2UsbmIxcG9wX1RhYmxlVklJSWJvdGgkZGYucmVzaWR1YWwpCnJlZ3RhYmxlMTg1NVRhYmxlVklJSVsxNSw4XSA8LSAxMDAwMCAqIHN1bShuYjFwb3BfVGFibGVWSUlJYm90aCRmaXR0ZWQudmFsdWVzWzE6MjhdKSAvIHN1bShyZWdkYXRhMTg1NVZJSWJvdGgkcG9wdWxhdGlvblsxOjI4XSkKcmVndGFibGUxODU1VGFibGVWSUlJWzE2LDhdIDwtIDEwMDAwICogc3VtKG5iMXBvcF9UYWJsZVZJSUlib3RoJGZpdHRlZC52YWx1ZXNbMjk6NDRdKSAvIHN1bShyZWdkYXRhMTg1NVZJSWJvdGgkcG9wdWxhdGlvblsyOTo0NF0pCgpgYGAKCgoKCmBgYHtyfQoKa2FibGUocmVndGFibGUxODU1VGFibGVWSUlJW2MoMSwzLDEwLDEyLDEzLDE0LDE1LDE2KSxjKDIsMyw2KV0sZGlnaXRzPTMsIGNhcHRpb24gPSAiU3VtbWFyeSAtIFF1YXNpLVJhbmRvbWl6ZWQgUmVncmVzc2lvbnMsIDE4NTUgVGFibGUgVklJSSAoNyB3ZWVrcyBlbmRpbmcgMjZ0aCBBdWcpIixmb3JtYXQ9J3BhbmRvYycpCgpgYGAKCkkgYW0gbm90IHByaW50aW5nIG91dCBhbGwgdGhlIHJlZ3Jlc3Npb25zICh5b3UgY2FuIGNoZWNrIHRoZSBzdW1tYXJ5IHN0YXRpc3RpY3MgaW4gdGhlIHRhYmxlKSwgYnV0IHRoZSByZXN1bHRzIGFyZToKCisgU2ltcGxlIFBvaXNzb24gaGFzIGEgaGlnaCBSZXNpZHVhbCBEZXZpYW5jZSAoIm92ZXJkaXNwZXJzaW9uIiksIGltcGx5aW5nIHRoYXQgUG9pc3NvbiBkb2VzIG5vdCBmaXQgdGhlIGRhdGEgd2VsbCwgYW5kIHRoYXQgdGhlIGVzdGltYXRlZCBzdGFuZGFyZCBlcnJvcnMgYXJlIHRvbyBzbWFsbC4KKyBJbmNsdWRpbmcgcG9wdWxhdGlvbiAoaG91c2luZykgZGVuc2l0eSBoYXMgYSBuZWdsaWdpYmxlIGVmZmVjdAorIEluY2x1ZGluZyBzdWItZGlzdHJpY3QgZml4ZWQgZWZmZWN0cyBnaXZlcyBhIFJlc2lkdWFsIERldmlhbmNlIHRoYXQgaXMgbWFyZ2luYWxseSBzaWduaWZpY2FudCAoUmVzaWR1YWwgRGV2aWFuY2UgPSBgciByb3VuZChwb2lzMl9UYWJsZVZJSUkkZGV2aWFuY2UsMilgLCBwLXZhbHVlID0gYHIgcm91bmQoMS1wY2hpc3EocG9pczJfVGFibGVWSUlJJGRldmlhbmNlLHBvaXMyX1RhYmxlVklJSSRkZi5yZXNpZHVhbCksMylgKS4gSW4gb3RoZXIgd29yZHMgUG9pc3NvbiB3aXRoIGVhY2ggc3ViLWRpc3RyaWN0IGhhdmluZyBhIGRpZmZlcmVudCByYXRlIGZpdHMgbWFyZ2luYWxseS4gCisgTmVnYXRpdmUgQmlub21pYWwgZml0cyB0aGUgZGF0YSBzbGlnaHRseSBiZXR0ZXIgKGluIHRlcm1zIG9mIFJlc2lkdWFsIERldmlhbmNlIC0gaXQgaXMgaGlnaGVyIHRoYW4gUG9pc3NvbiB3aXRoIEZpeGVkIEVmZmVjdHMsIGJ1dCByZXF1aXJlcyBmZXdlciBleHBsYW5hdG9yeSB2YXJpYWJsZXMgdG8gcmVkdWNlIHRoZSBEZXZpYW5jZSkuIAorIEluIGFsbCBjYXNlcyB0aGUgIkxhbWJldGggRWZmZWN0IiBpcyBsYXJnZSAocm91Z2hseSBgciByb3VuZChwb2lzMl9UYWJsZVZJSUkkY29lZmZpY2llbnRzWzJdLDEpYCBmb3IgYSByYXRpbyBlZmZlY3Qgb2YgYHIgcm91bmQoZXhwKC1wb2lzMl9UYWJsZVZJSUkkY29lZmZpY2llbnRzWzJdKSwxKWApLiAKKyBUaGUgIkxhbWJldGggRWZmZWN0IiBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IChoYXMgYSB2ZXJ5IGxhcmdlIHotdmFsdWUpLiBXZSBjYW5ub3QgcmVseSBvbiB0aGUgei12YWx1ZSBmb3IgdGhlIGJhc2ljIFBvaXNzb24gcmVncmVzc2lvbiAoYmVjYXVzZSB0aGUgbW9kZWwgZG9lcyBub3QgZml0IHdlbGwgLSB0aGUgUmVzaWR1YWwgRGV2aWFuY2UgaXMgbGFyZ2UpLCBhbmQgd2Ugd2FudCB0byBiZSBjYXV0aW91cyBldmVuIHdpdGggdGhlIFBvaXNzb24gRkUgbW9kZWwuIEJ1dCB0aGUgTmVnYXRpdmUgQmlub21pYWwgc3RpbGwgaGFzIGEgdmVyeSBsYXJnZSB6LXZhbHVlLiBGdXJ0aGVyLCB3ZSBjYW4gY2FsY3VsYXRlIHJvYnVzdCBzdGFuZGFyZCBlcnJvcnMgZm9yIGFsbCB0aGUgcmVncmVzc2lvbnMsIGFuZCB0aGVzZSBhbGwgaGF2ZSBsYXJnZSB6LXZhbHVlcyAoOCBvciBsYXJnZXIpCgoKIyMjI0dyYXBocyBTaG93aW5nIFN1Yi1EaXN0cmljdCBWYXJpYXRpb24KCkdyYXBoaW5nIHRoZSBhY3R1YWwgdmVyc3VzIGZpdHRlZCB2YWx1ZXMsIHRvZ2V0aGVyIHdpdGggYXBwcm94aW1hdGUgc3RhbmRhcmQgZXJyb3JzLCBoZWxwcyB1cyBzZWUgd2h5IHRoZSBQb2lzc29uIHJlZ3Jlc3Npb24gZG9lcyBub3QgZml0IHRoZSBkYXRhLiBUaGUgZm9sbG93aW5nIGNvZGUgY2h1bmsgcHJvZHVjZXMgdGhlIGdyYXBoLiAKCmBgYHtyfQojICJXb3JrZXIiIGZ1bmN0aW9uIHRvIHBsb3QgbWVhbiwgcHJlZGljdGVkLCBhbmQgZXJyb3IgYmFycwpwbG90Ml93b3JrZXIgPC0gZnVuY3Rpb24oeXNlcSwgeG1lYW4seGxpbWRuLHhwcmVkLHhsaW11cCx0aXRsZSkgeyAgICAgICAgICAgIAoJeHBsb3QgPC0gcGxvdCh4bWVhbiwgeXNlcSwKCSAgICB4bGltPXJhbmdlKGMoeG1lYW4sIHhwcmVkLHhsaW1kbix4bGltdXApKSwKCSAgICB5bGltPXJldihyYW5nZSh5c2VxKSksIGNvbD0icmVkIiwKCSAgICBtYWluPXRpdGxlLHhsYWI9Ik1vcnRhbGl0eSByYXRlIGFjdHVhbCAocmVkIGZpbGxlZCkgdnMgcHJlZGljdGVkIChlbXB0eSBjaXJjbGUpIix5bGFiPSJzdWItZGlzdHJpY3QiLAoJICAgIHBjaD0xOSkKCWxpbmVzKHhwcmVkLCB5c2VxLCB0eXBlPSJwIiwKCSAgICB4bGltPXJhbmdlKGMoeG1lYW4sIHhwcmVkLHhsaW1kbix4bGltdXApKSwKCSAgICB5bGltPXJldihyYW5nZSh5c2VxKSksIAoJICAgIHBjaD0xKQoJIyBob3Jpem9udGFsIGVycm9yIGJhcnMKCXhwbG90IDwtIGFycm93cyh4bGltZG4sIHlzZXEsIHhsaW11cCwgeXNlcSwgbGVuZ3RoPTAuMDUsIGFuZ2xlPTkwLCBjb2RlPTMsbHR5PTMpCgl4cGxvdAp9CgojIFBvaXNzb24gUmVncmVzc2lvbiBHcmFwaAoKIyAyLjUsIG1lYW4sIDk3LjUgcXVhbnRpbGVzIGZvciB0aGUgIm5leHQgMTYiIHN1Yi1kaXN0cmljdHMsIHNlcGFyYXRlbHkgYnkgU291dGh3YXJrIHZzIAojIExhbWJldGggcG9wdWxhdGlvbnMsIGZvciBQb2lzc29uIHJlZ3Jlc3Npb24KeHgxY291bnQgPC0gcG9pczFfVGFibGVWSUlJJGZpdHRlZC52YWx1ZXMKeHgxcmF0ZSA8LSAxMDAwMCAqIHh4MWNvdW50IC8gcmVnZGF0YTE4NTVWSUlqb2ludCRwb3B1bGF0aW9uCgp4MjUgPC0gMTAwMDAgKiBxcG9pcyguMDI1LGxhbWJkYT14eDFjb3VudFsxOjE2XSkgLyByZWdkYXRhMTg1NVZJSWpvaW50JHBvcHVsYXRpb25bMToxNl0KeDk3NSA8LSAxMDAwMCAqIHFwb2lzKC45NzUsbGFtYmRhPXh4MWNvdW50WzE6MTZdKSAvIHJlZ2RhdGExODU1VklJam9pbnQkcG9wdWxhdGlvblsxOjE2XQojcGRmKHBhc3RlKCIuLi9wYXBlci9maWd1cmVzL2VycmJhcl9wb2lzMV9UYWJsZVZJSUkiLCJjLnBkZiIsc2VwPSIiKSkKCXA1IDwtIHBsb3QyX3dvcmtlcigxMzoyOCwgcmVnZGF0YTE4NTVWSUlqb2ludCRyYXRlWzE6MTZdLHgyNSx4eDFyYXRlWzE6MTZdLHg5NzUsCgkJIkpvaW50IDE4NTQgUG9pc3NvbiBBY3QgdnMgUHJlZCwgU291dGh3YXJrIFN1cHBsaWVkIikKI2Rldi5vZmYoKQp4MjUgPC0gMTAwMDAgKiBxcG9pcyguMDI1LGxhbWJkYT14eDFjb3VudFsxNzozMl0pIC8gcmVnZGF0YTE4NTVWSUlqb2ludCRwb3B1bGF0aW9uWzE3OjMyXQp4OTc1IDwtIDEwMDAwICogcXBvaXMoLjk3NSxsYW1iZGE9eHgxY291bnRbMTc6MzJdKSAvIHJlZ2RhdGExODU1VklJam9pbnQkcG9wdWxhdGlvblsxNzozMl0KeDk3NSA8LSBwbWluKHg5NzUsMjApCiNwZGYocGFzdGUoIi4uL3BhcGVyL2ZpZ3VyZXMvZXJyYmFyX3BvaXMxX1RhYmxlVklJSSIsImQucGRmIixzZXA9IiIpKQoJcDYgPC0gcGxvdDJfd29ya2VyKDEzOjI4LCByZWdkYXRhMTg1NVZJSWpvaW50JHJhdGVbMTc6MzJdLHgyNSx4eDFyYXRlWzE3OjMyXSx4OTc1LAoJICAgIkpvaW50IDE4NTQgUG9pc3NvbiBBY3QgdnMgUHJlZCwgTGFtYmV0aCBTdXBwbGllZCIpCiNkZXYub2ZmKCkKYGBgCgpUaGUgb2JzZXJ2ZWQgbW9ydGFsaXR5IHJhdGVzIChyZWQgY2lyY2xlcykgYXJlIHF1aXRlIHZhcmlhYmxlIGNvbXBhcmVkIHdpdGggdGhlIGZpdHRlZCB2YWx1ZXMsIG9mdGVuIGZhbGxpbmcgb3V0c2lkZSB0aGUgYXBwcm94aW1hdGUgZXJyb3IgYmFycy4gVGhlIGRpZmZlcmVuY2UgYmV0d2VlbiBTb3V0aHdhcmsgJiBWYXV4aGFsbCBDby4gY3VzdG9tZXJzICh0aGUgZmlyc3QgZ3JhcGgpIHZlcnN1cyBMYW1iZXRoIENvLiBjdXN0b21lcnMgaXMgbm9uZXRoZWxlc3MgdmVyeSBsYXJnZS4gCgpXZSBjYW4gYWNjb21tb2RhdGUgdGhlIG91dGxpZXJzIHdpdGhpbiB0aGUgZXJyb3IgYmFycyBiZXR0ZXIgZWl0aGVyIGJ5IGFsbG93aW5nIGVhY2ggc3ViLWRpc3RyaWN0IHRvIGJlIGRpZmZlcmVudCAoaW5jbHVkaW5nIHN1Yi1kaXN0cmljdCBmaXhlZCBlZmZlY3RzKSwgb3IgYnkgd2lkZW5pbmcgdGhlIGVycm9yIGJhcnMgdGhlbXNlbHZlcyAoYXNzdW1pbmcgdGhlIGVycm9ycyBhcmUgTmVnYXRpdmUgQmlub21pYWwsIGVzc2VudGlhbGx5IHRoYXQgdGhlIHN1Yi1kaXN0cmljdHMgaGF2ZSByYW5kb20gbW9ydGFsaXR5IHJhdGVzKS4gRm9yIHRoaXMgc2V0IG9mIGRhdGEgZWl0aGVyIGFwcHJvYWNoIHdvcmtzIHNvbWV3aGF0IHdlbGwsIGFzIHNob3duIGJ5IHRoZSBSZXNpZHVhbCBEZXZpYW5jZSBjYWxjdWxhdGlvbnMgaW4gdGhlIHRhYmxlIGFib3ZlLiAKClRoZSBmb2xsb3dpbmcgdHdvIGNvZGUgY2h1bmtzIHdpbGwgcHJvZHVjZSBncmFwaHMgZm9yIFBvaXNzb24gRkVzIGFuZCBOZWdhdGl2ZSBCaW5vbWlhbC4gSSBoYXZlIGNvbW1lbnRlZCBvdXQgdGhlIGFjdHVhbCBwbG90IGNvbW1hbmQgKHRoZSBjYWxsIHRvICJwbG90Ml93b3JrZXIiKSBidXQgeW91IGNhbiBlYXNpbHkgcnVuIHRoZXNlIGNodW5rcyB5b3Vyc2VsZiB0byBzZWUgdGhlIGdyYXBocy4gCgpgYGB7cn0KCiMgUG9pc3NvbiBSZWdyZXNzaW9uIEZFIEdyYXBoCgojIDIuNSwgbWVhbiwgOTcuNSBxdWFudGlsZXMgZm9yIHRoZSAibmV4dCAxNiIgc3ViLWRpc3RyaWN0cywgc2VwYXJhdGVseSBieSBTb3V0aHdhcmsgdnMgCiMgTGFtYmV0aCBwb3B1bGF0aW9ucywgZm9yIFBvaXNzb24gcmVncmVzc2lvbgp4eDFjb3VudCA8LSBwb2lzMl9UYWJsZVZJSUkkZml0dGVkLnZhbHVlcwp4eDFyYXRlIDwtIDEwMDAwICogeHgxY291bnQgLyByZWdkYXRhMTg1NVZJSWpvaW50JHBvcHVsYXRpb24KCngyNSA8LSAxMDAwMCAqIHFwb2lzKC4wMjUsbGFtYmRhPXh4MWNvdW50WzE6MTZdKSAvIHJlZ2RhdGExODU1VklJam9pbnQkcG9wdWxhdGlvblsxOjE2XQp4OTc1IDwtIDEwMDAwICogcXBvaXMoLjk3NSxsYW1iZGE9eHgxY291bnRbMToxNl0pIC8gcmVnZGF0YTE4NTVWSUlqb2ludCRwb3B1bGF0aW9uWzE6MTZdCiNwZGYocGFzdGUoIi4uL3BhcGVyL2ZpZ3VyZXMvZXJyYmFyX3BvaXMyX1RhYmxlVklJSSIsImMucGRmIixzZXA9IiIpKQojCXA1IDwtIHBsb3QyX3dvcmtlcigxMzoyOCwgcmVnZGF0YTE4NTVWSUlqb2ludCRyYXRlWzE6MTZdLHgyNSx4eDFyYXRlWzE6MTZdLHg5NzUsICJKb2ludCAxODU0IFBvaXNzb24gRkUgQWN0IHZzIFByZWQsIFNvdXRod2FyayBTdXBwbGllZCIpCiNkZXYub2ZmKCkKeDI1IDwtIDEwMDAwICogcXBvaXMoLjAyNSxsYW1iZGE9eHgxY291bnRbMTc6MzJdKSAvIHJlZ2RhdGExODU1VklJam9pbnQkcG9wdWxhdGlvblsxNzozMl0KeDk3NSA8LSAxMDAwMCAqIHFwb2lzKC45NzUsbGFtYmRhPXh4MWNvdW50WzE3OjMyXSkgLyByZWdkYXRhMTg1NVZJSWpvaW50JHBvcHVsYXRpb25bMTc6MzJdCng5NzUgPC0gcG1pbih4OTc1LDIwKQojcGRmKHBhc3RlKCIuLi9wYXBlci9maWd1cmVzL2VycmJhcl9wb2lzMl9UYWJsZVZJSUkiLCJkLnBkZiIsc2VwPSIiKSkKIwlwNiA8LSBwbG90Ml93b3JrZXIoMTM6MjgsIHJlZ2RhdGExODU1VklJam9pbnQkcmF0ZVsxNzozMl0seDI1LHh4MXJhdGVbMTc6MzJdLHg5NzUsIkpvaW50IDE4NTQgUG9pc3NvbiBGRSBBY3QgdnMgUHJlZCwgTGFtYmV0aCBTdXBwbGllZCIpCiNkZXYub2ZmKCkKYGBgCgoKYGBge3J9CgojIE5lZ2F0aXZlIEJpbm9taWFsIFBvcHVsYXRpb24gRGVuc2l0eSBHcmFwaAojIE5vdGUgdGhlIGRpZmZlcmVuY2UgZnJvbSB0aGUgY29kZSBjaHVua3MgYWJvdmUgLSB1c2luZyBxbmJpbm9tKCkgcmF0aGVyIHRoYW4gcXBvaXNzKCkKCiMgMi41LCBtZWFuLCA5Ny41IHF1YW50aWxlcyBmb3IgdGhlICJuZXh0IDE2IiBzdWItZGlzdHJpY3RzLCBzZXBhcmF0ZWx5IGJ5IFNvdXRod2FyayB2cyAKIyBMYW1iZXRoIHBvcHVsYXRpb25zCnRoZXRhIDwtIG5iMXBvcF9UYWJsZVZJSUkkdGhldGEKeHgxY291bnQgPC0gbmIxcG9wX1RhYmxlVklJSSRmaXR0ZWQudmFsdWVzCnh4MXJhdGUgPC0gMTAwMDAgKiB4eDFjb3VudCAvIHJlZ2RhdGExODU1VklJam9pbnQkcG9wdWxhdGlvbgoKeDI1IDwtIDEwMDAwICogcW5iaW5vbSguMDI1LHNpemU9dGhldGEsbXU9eHgxY291bnRbMToxNl0pIC8gcmVnZGF0YTE4NTVWSUlqb2ludCRwb3B1bGF0aW9uWzE6MTZdCng5NzUgPC0gMTAwMDAgKiBxbmJpbm9tKC45NzUsc2l6ZT10aGV0YSxtdT14eDFjb3VudFsxOjE2XSkgLyByZWdkYXRhMTg1NVZJSWpvaW50JHBvcHVsYXRpb25bMToxNl0KI3BkZihwYXN0ZSgiLi4vcGFwZXIvZmlndXJlcy9lcnJiYXJfbmIxcG9wX1RhYmxlVklJSSIsImMucGRmIixzZXA9IiIpKQojCXA1IDwtIHBsb3QyX3dvcmtlcigxMzoyOCwgcmVnZGF0YTE4NTVWSUlqb2ludCRyYXRlWzE6MTZdLHgyNSx4eDFyYXRlWzE6MTZdLHg5NzUsIkpvaW50IDE4NTQgTmVnQmlub20rUG9wRGVuIEFjdCB2cyBQcmVkLCBTb3V0aHdhcmsgU3VwcGxpZWQiKQojZGV2Lm9mZigpCngyNSA8LSAxMDAwMCAqIHFuYmlub20oLjAyNSxzaXplPXRoZXRhLG11PXh4MWNvdW50WzE3OjMyXSkgLyByZWdkYXRhMTg1NVZJSWpvaW50JHBvcHVsYXRpb25bMTc6MzJdCng5NzUgPC0gMTAwMDAgKiBxbmJpbm9tKC45NzUsc2l6ZT10aGV0YSxtdT14eDFjb3VudFsxNzozMl0pIC8gcmVnZGF0YTE4NTVWSUlqb2ludCRwb3B1bGF0aW9uWzE3OjMyXQp4OTc1IDwtIHBtaW4oeDk3NSwyMCkKI3BkZihwYXN0ZSgiLi4vcGFwZXIvZmlndXJlcy9lcnJiYXJfbmIxcG9wX1RhYmxlVklJSSIsImQucGRmIixzZXA9IiIpKQojCXA2IDwtIHBsb3QyX3dvcmtlcigxMzoyOCwgcmVnZGF0YTE4NTVWSUlqb2ludCRyYXRlWzE3OjMyXSx4MjUseHgxcmF0ZVsxNzozMl0seDk3NSwiSm9pbnQgMTg1NCBOZWdCaW5vbStQb3BEZW4gQWN0IHZzIFByZWQsIExhbWJldGggU3VwcGxpZWQiKQojZGV2Lm9mZigpCmBgYAoKIyMjI0NvbmNsdXNpb24KCkluIHN1bW1hcnksIG1vcnRhbGl0eSBkYXRhIGJ5IHN1Yi1kaXN0cmljdCBmb3IgdGhlIHNldmVuIHdlZWtzIGVuZGluZyAyNnRoIEF1Z3VzdCAxODU0LCBzcGxpdCBieSB3YXRlciBzdXBwbGllciwgc3Ryb25nbHkgc3VwcG9ydCB0aGUgY29uY2x1c2lvbiB0aGF0IHdhdGVyIHN1cHBseSAoZGlydHkgZm9yIFNvdXRod2FyayAmIFZhdXhoYWxsIENvLiwgY2xlYW4gZm9yIExhbWJldGggQ28uKSBoYXMgYSB2ZXJ5IGxhcmdlIGltcGFjdCBvbiBtb3J0YWxpdHkuIFRoaXMgY29uY2x1c2lvbiBob2xkcyBpbiB0aGUgcHJlc2VuY2Ugb2YgbGFyZ2UgdmFyaWF0aW9ucyBhY3Jvc3Mgc3ViLWRpc3RyaWN0cy4gVGhlIGVmZmVjdCBvZiBjbGVhbiB3YXRlciBpcyBkcmFtYXRpY2FsbHkgbGFyZ2VyIHRoYW4sIGFuZCBpcyB1bmFmZmVjdGVkIGJ5LCB2YXJpYXRpb24gaW4gaG91c2luZyBkZW5zaXR5LiAKCgoKCgoKIyMjQ291bnQgUmVncmVzc2lvbnMgZm9yIFNub3cgMTg1NiBUYWJsZSBWIChieSBEaXN0cmljdCkKClNub3cgMTg1NiBUYWJsZSBWIHNob3dzIGRlYXRocyBieSBEaXN0cmljdCAoOSBEaXN0cmljdHMgcmF0aGVyIHRoYW4gMzIgc3ViLWRpc3RyaWN0cykgYW5kIHdhdGVyIHNvdXJjZSAoU291dGh3YXJrIENvLCBMYW1iZXRoIENvLCAiT3RoZXIiKS4gCgpgYGB7cn0Ka2FibGUodGFibGVWXzE4NTZbLGMoImRpc3RyaWN0IiwiZGVhdGhzX3NvdXRod2FyayIsImRlYXRoc19sYW1iZXRoIiwiZGVhdGhzX3B1bXBzIiwiZGVhdGhzX3VuYXNjZXJ0YWluZWQiLCJkZWF0aHNfdG90YWwiKV0sZGlnaXRzPTMsIGNhcHRpb24gPSAiRGVhdGhzIGJ5IFN1cHBsaWVyIGZyb20gMTg1NiBUYWJsZSBWIixmb3JtYXQ9J3BhbmRvYycpCgpgYGAKCgpUaGVyZSBhcmUgdHdvIGFkdmFudGFnZXMgYW5kIHR3byBkaXNhZHZhbnRhZ2VzIHJlbGF0aXZlIHRvIFNub3cgMTg1NSBUYWJsZSBWSUlJOgoKKipBZHZhbnRhZ2VzKio6IERlYXRocyBjb3ZlciB0aGUgY29tcGxldGUgZXBpZGVtaWMgKHRocm91Z2ggT2N0b2JlciAxODU0KSB3aGljaCBtYXRjaGVzIFNub3cgMTg1NSBUYWJsZSBYSUk7IEZld2VyIHByb2JsZW1zIHdpdGggcG9vciBwb3B1bGF0aW9uIGVzdGltYXRlcyBmb3IgU291dGh3YXJrIHZlcnN1cyBMYW1iZXRoIGN1c3RvbWVycwoKKipEaXNhZHZhbnRhZ2UqKjogTWFueSBtb3JlICJub3QgYXNjZXJ0YWluZWQiIG9yICJ1bmFzY2VydGFpbmVkIiBjYXNlcyBpbiBhc3NpZ25pbmcgZGVhdGhzIHdpdGhpbiBEaXN0cmljdCB0byB3YXRlciBzb3VyY2UgKFNvdXRod2FyayBDbyBvciBMYW1iZXRoIENvIC0gdGhlIFJlZ2lzdHJhci1HZW5lcmFsIHdhcyBmYXIgbGVzcyBjYXJlZnVsIGNvbGxlY3RpbmcgZGF0YSBhZnRlciAyNnRoIEF1Z3VzdCB0aGFuIFNub3cgaGFkIGJlZW4gdXAgdG8gMjZ0aCBBdWd1c3QpOyBMZXNzIGdlb2dyYXBoaWMgb3IgbG9jYXRpb24gZGV0YWlsLCB3aXRoIGRlYXRocyByZXBvcnRlZCBieSBEaXN0cmljdCByYXRoZXIgdGhhbiBzdWItZGlzdHJpY3QuIAoKCiMjIyNQcmVwYXJlIERhdGEKClRoZXJlIGFyZSB0d28gc3Vic3RhbnRpdmUgbW9kaWZpY2F0aW9ucyB0byB0aGUgZGF0YSB0aGF0IHdlIGhhdmUgdG8gbWFrZSAoYXBhcnQgZnJvbSBzaW1wbHkgc3RhY2tpbmcgdGhlIGRhdGEgdG8gc2V0IHVwIGZvciByZWdyZXNzaW9ucyk6CgorIEFsbG9jYXRlIHRoZSAibm90IGFzY2VydGFpbmVkIiAob3IgInVuYXNjZXJ0YWluZWQiKSBkZWF0aHMgd2l0aGluIGEgRGlzdHJpY3QgdG8gc3VwcGxpZXIsIHRoZSBTb3V0aHdhcmsgJiBWYXV4aGFsbCBDby4gb3IgdGhlIExhbWJldGggQ28uIEFzIHN1Z2dlc3RlZCBieSBTbm93LCB0aGUgc2ltcGxlc3QgYW5kIG1vc3QgcmVhc29uYWJsZSBhcHByb2FjaCBzZWVtcyB0byBiZSBzaW1wbHkgYWxsb2NhdGluZyBieSB0aGUgd2l0aGluLURpc3RyaWN0IHByb3BvcnRpb25zIChzZWUgU25vdyAxODU2IHAuIDI0NzogIkksIHRoZXJlZm9yZSwgY29uY2x1ZGVkIHRoYXQgSSBjb3VsZCBub3QgYmUgd3JvbmcgaW4gZGl2aWRpbmcgdGhlIG5vbi1hc2NlcnRhaW5lZCBjYXNlcyBiZXR3ZWVuIHRoZSB0d28gY29tcGFuaWVzIGluIHRoZSBzYW1lIHByb3BvcnRpb24gYXMgdGhvc2Ugd2hpY2ggd2VyZSBhc2NlcnRhaW5lZCIpLiBCZWNhdXNlIHdlIHdpbGwgdXNlIHRoZXNlIGRhdGEgZm9yIGNvdW50IHJlZ3Jlc3Npb25zICh3aGljaCByZXF1aXJlIGludGVnZXIgdmFsdWVzKSwgSSByb3VuZCB0aGUgcmVzdWx0LgorIFJlbW92ZSBjb3VudHMgZm9yIEJlcm1vbmRzZXkgYW5kIE5ld2luZ3RvbiBmb3IgIk90aGVyIiBiZWNhdXNlIHRoZXkgc2hvdyBuZWdhdGl2ZSAiT3RoZXIiIHBvcHVsYXRpb24gKFNvdXRod2FyayArIExhbWJldGggY29tYmluZWQgZXN0aW1hdGVkIHBvcHVsYXRpb24gZ3JlYXRlciB0aGFuIDE4NTEgY2Vuc3VzKS4gVGhpcyBpcyBub3QgYSBnb29kIHdheSB0byBoYW5kbGUgdGhlIHByb2JsZW0gYnV0IEkgY2FuJ3QgZmlndXJlIG91dCBhbnkgYmV0dGVyCgoKYGBge3J9CiMgQWxsb2NhdGUgInVuYXNjZXJ0YWluZWQiIHdpdGhpbiBSZWdpc3RyYXRpb24gRGlzdHJpY3QgYWNjb3JkaW5nIHRvIHJhdGlvIG9mIG9ic2VydmVkIAojIFNvdXRod2FyayB2cyBMYW1iZXRoIGRlYXRocwp0YWJsZVZfMTg1NiRkZWF0aHNfc291dGh3YXJrX2FkaiA8LSB0YWJsZVZfMTg1NiRkZWF0aHNfc291dGh3YXJrICsgcm91bmQodGFibGVWXzE4NTYkZGVhdGhzX3VuYXNjZXJ0YWluZWQqdGFibGVWXzE4NTYkZGVhdGhzX3NvdXRod2Fyay8odGFibGVWXzE4NTYkZGVhdGhzX3NvdXRod2Fyayt0YWJsZVZfMTg1NiRkZWF0aHNfbGFtYmV0aCksMCkKCnRhYmxlVl8xODU2JGRlYXRoc19sYW1iZXRoX2FkaiA8LSB0YWJsZVZfMTg1NiRkZWF0aHNfbGFtYmV0aCArIHJvdW5kKHRhYmxlVl8xODU2JGRlYXRoc191bmFzY2VydGFpbmVkKnRhYmxlVl8xODU2JGRlYXRoc19sYW1iZXRoLyh0YWJsZVZfMTg1NiRkZWF0aHNfc291dGh3YXJrK3RhYmxlVl8xODU2JGRlYXRoc19sYW1iZXRoKSwwKQoKeDEgPC0gdGFibGVWXzE4NTZbMTo5LF0KIyBTb3V0aHdhcmsKeHNvdXRod2FyayA8LSB4MVtjKCJkaXN0cmljdCIsImRpc3RyaWN0SUQiLCJkZW5zaXR5X1Nub3ciLCJwb3Bfc291dGh3YXJrIiwiZGVhdGhzX3NvdXRod2Fya19hZGoiKV0KY29sbmFtZXMoeHNvdXRod2FyaykgPC0gYygiZGlzdHJpY3QiLCJkaXN0cmljdElEIiwiZGVuc2l0eV9Tbm93IiwicG9wIiwiZGVhdGhzX2FkaiIpCnhzb3V0aHdhcmskc3VwcGxpZXIgPC0gIlNvdXRod2FyayIKIyBMYW1iZXRoCnhsYW1iZXRoIDwtIHgxW2MoImRpc3RyaWN0IiwiZGlzdHJpY3RJRCIsImRlbnNpdHlfU25vdyIsInBvcF9sYW1iZXRoIiwiZGVhdGhzX2xhbWJldGhfYWRqIildCmNvbG5hbWVzKHhsYW1iZXRoKSA8LSBjKCJkaXN0cmljdCIsImRpc3RyaWN0SUQiLCJkZW5zaXR5X1Nub3ciLCJwb3AiLCJkZWF0aHNfYWRqIikKeGxhbWJldGgkc3VwcGxpZXIgPC0gInhMYW1iZXRoIgojIFJlbW92ZSBTdC4gT2xhdmUsIFNvdXRod2FyayBhbmQgUm90aGVyaGl0aGUgZnJvbSBMYW1iZXRoIGRhdGEgKHNpbmNlIDAgcG9wdWxhdGlvbikKeGxhbWJldGggPC0geGxhbWJldGhbLWMoMiw5KSxdCiMgT3RoZXIKeG90aGVyIDwtIHgxW2MoImRpc3RyaWN0IiwiZGlzdHJpY3RJRCIsImRlbnNpdHlfU25vdyIsInBvcF9sYW1iZXRoIiwiZGVhdGhzX2xhbWJldGhfYWRqIildCmNvbG5hbWVzKHhvdGhlcikgPC0gYygiZGlzdHJpY3QiLCJkaXN0cmljdElEIiwiZGVuc2l0eV9Tbm93IiwicG9wIiwiZGVhdGhzX2FkaiIpCnhvdGhlciRwb3AgPC0geDEkcG9wMTg1MSAtICh4MSRwb3Bfc291dGh3YXJrICsgeDEkcG9wX2xhbWJldGgpCnhvdGhlciRkZWF0aHNfYWRqIDwtIHgxJGRlYXRoc19wdW1wcwp4b3RoZXIkc3VwcGxpZXIgPC0gInhPdGhlciIKIyBSZW1vdmUgQmVybW9uZHNleSAmIE5ld2luZ3RvbiAmIExhbWJldGggYmVjYXVzZSB0aGV5IHNob3cgbmVnYXRpdmUgKG9yIHZlcnkgbG93KSBwdW1wIHBvcHVsYXRpb24gKFNvdXRod2FyayArIExhbWJldGgKIyBjb21iaW5lZCBlc3RpbWF0ZWQgcG9wdWxhdGlvbiBncmVhdGVyIHRoYW4gMTg1MSBjZW5zdXMpCiMgVGhpcyBpcyBub3QgYSBnb29kIHdheSB0byBoYW5kbGUgdGhlIHByb2JsZW0gYnV0IEkgY2FuJ3QgZmlndXJlIG91dCBhbnkgYmV0dGVyCnhvdGhlciA8LSB4b3RoZXJbLWMoMyw1LDYpLF0KCnJlZ2RhdGFfMTg1NlZfMnN1cHAgPC0gcmJpbmQoeHNvdXRod2Fyayx4bGFtYmV0aCkKcmVnZGF0YV8xODU2Vl8zc3VwcCA8LSByYmluZCh4c291dGh3YXJrLHhsYW1iZXRoLHhvdGhlcikKCgpgYGAKCiMjIyNVbmRlcmx5aW5nIERhdGEgZm9yIFF1YXNpLVJhbmRvbWl6ZWQgQ29tcGFyaXNvbgoKYGBge3J9Cgp0YWJsZVZfZGlzcGxheSA8LSB0YWJsZVZfMTg1NlssYygiZGlzdHJpY3QiLCJkZWF0aHNfc291dGh3YXJrX2FkaiIsImRlYXRoc19sYW1iZXRoX2FkaiIsImRlYXRoc19wdW1wcyIsImRlYXRoc190b3RhbCIsInBvcDE4NTEiLCJwb3Bfc291dGh3YXJrIiwicG9wX2xhbWJldGgiKV0KdGFibGVWX2Rpc3BsYXkkbW9ydGFsaXR5X3NvdXRod2FyayA8LSAxMDAwMCAqIHRhYmxlVl9kaXNwbGF5JGRlYXRoc19zb3V0aHdhcmtfYWRqIC8gdGFibGVWX2Rpc3BsYXkkcG9wX3NvdXRod2Fyawp0YWJsZVZfZGlzcGxheSRtb3J0YWxpdHlfbGFtYmV0aCA8LSAxMDAwMCAqIHRhYmxlVl9kaXNwbGF5JGRlYXRoc19sYW1iZXRoX2FkaiAvIHRhYmxlVl9kaXNwbGF5JHBvcF9sYW1iZXRoCnRhYmxlVl9kaXNwbGF5JG1vcnRhbGl0eV9wdW1wcyA8LSAxMDAwMCAqIHRhYmxlVl9kaXNwbGF5JGRlYXRoc19wdW1wcyAvICh0YWJsZVZfZGlzcGxheSRwb3AxODUxIC0gdGFibGVWX2Rpc3BsYXkkcG9wX3NvdXRod2FyayAtIHRhYmxlVl9kaXNwbGF5JHBvcF9sYW1iZXRoKQp0YWJsZVZfZGlzcGxheSRwb3BfcHVtcHMgPC0gdGFibGVWX2Rpc3BsYXkkcG9wMTg1MSAtIHRhYmxlVl9kaXNwbGF5JHBvcF9zb3V0aHdhcmsgLSB0YWJsZVZfZGlzcGxheSRwb3BfbGFtYmV0aAp0YWJsZVZfZGlzcGxheSRwZXJjZW50X3NvdXRod2FyayA8LSAxMDAgKiB0YWJsZVZfZGlzcGxheSRwb3Bfc291dGh3YXJrIC8gdGFibGVWX2Rpc3BsYXkkcG9wMTg1MQp0YWJsZVZfZGlzcGxheSRwZXJjZW50X2xhbWJldGggPC0gMTAwICogdGFibGVWX2Rpc3BsYXkkcG9wX2xhbWJldGggLyB0YWJsZVZfZGlzcGxheSRwb3AxODUxCnRhYmxlVl9kaXNwbGF5JHBlcmNlbnRfcHVtcHMgPC0gMTAwIC0gdGFibGVWX2Rpc3BsYXkkcGVyY2VudF9zb3V0aHdhcmsgLSB0YWJsZVZfZGlzcGxheSRwZXJjZW50X2xhbWJldGgKa2FibGUodGFibGVWX2Rpc3BsYXlbYygxLDIsMyw0LDUsNiw3LDgsOSwxMiksYygiZGlzdHJpY3QiLCJwb3AxODUxIiwicG9wX3NvdXRod2FyayIsIm1vcnRhbGl0eV9zb3V0aHdhcmsiLCJwb3BfbGFtYmV0aCIsCiAgICAgICAgICAibW9ydGFsaXR5X2xhbWJldGgiLCJwb3BfcHVtcHMiLCJtb3J0YWxpdHlfcHVtcHMiKV0sZGlnaXRzPTEsIGNhcHRpb24gPSAiTW9ydGFsaXR5IGJ5IFN1cHBsaWVyIGZyb20gMTg1NiBUYWJsZSBWIChhZnRlciBhbGxvY2F0aW5nIHVuYXNzaWduZWQpIixmb3JtYXQ9J3BhbmRvYycpCgpgYGAKCgoKIyMjI1BvaXNzb24gUmVncmVzc2lvbnMKClRoZSBmb2xsb3dpbmcgY29kZSBjaHVuayBydW5zIFBvaXNzb24gcmVncmVzc2lvbiAoYnV0IGRvZXMgbm90IHByaW50IG91dCByZXN1bHRzKTogYmFzaWMsIHdpdGggcG9wdWxhdGlvbiBkZW5zaXR5LCBGaXhlZCBFZmZlY3RzLgoKYGBge3J9CiMgLS0tLS0tLSAgTm93IENvdW50IFJlZ3Jlc3Npb25zIHdpdGggU3VwcGxpZXIgPSBTb3V0aHdhcmssIExhbWJldGgsIGFuZCBPdGhlciAKIyBQb2lzc29uIHdpdGggbm8gZGVuc2l0eQpwb2lzMV9UYWJsZVYgPC0gZ2xtKGRlYXRoc19hZGogfiBzdXBwbGllciAKCSsgb2Zmc2V0KGxvZyhwb3ApKSwgZmFtaWx5PXBvaXNzb24sIGRhdGE9cmVnZGF0YV8xODU2Vl8zc3VwcCkKcG9pczFfVGFibGVWcm9idXN0c2UgPC0gY29lZnRlc3QocG9pczFfVGFibGVWLCB2Y292ID0gdmNvdkhDKHBvaXMxX1RhYmxlVikpCiNzdW1tYXJ5KHBvaXMxX1RhYmxlVikKCiMgUG9pc3NvbiB3aXRoIHllcyBkZW5zaXR5CnBvaXMxcG9wX1RhYmxlViA8LSBnbG0oZGVhdGhzX2FkaiB+IHN1cHBsaWVyICsgZGVuc2l0eV9Tbm93CgkrIG9mZnNldChsb2cocG9wKSksIGZhbWlseT1wb2lzc29uLCBkYXRhPXJlZ2RhdGFfMTg1NlZfM3N1cHApCnBvaXMxcG9wX1RhYmxlVnJvYnVzdHNlIDwtIGNvZWZ0ZXN0KHBvaXMxcG9wX1RhYmxlViwgdmNvdiA9IHZjb3ZIQyhwb2lzMXBvcF9UYWJsZVYpKQojc3VtbWFyeShwb2lzMXBvcF9UYWJsZVYpCgojIFBvaXNzb24gd2l0aCBGRQpwb2lzRkVfVGFibGVWIDwtIGdsbShkZWF0aHNfYWRqIH4gc3VwcGxpZXIgKyBkaXN0cmljdAoJKyBvZmZzZXQobG9nKHBvcCkpLCBmYW1pbHk9cG9pc3NvbiwgZGF0YT1yZWdkYXRhXzE4NTZWXzNzdXBwKQpwb2lzRkVfVGFibGVWcm9idXN0c2UgPC0gY29lZnRlc3QocG9pc0ZFX1RhYmxlViwgdmNvdiA9IHZjb3ZIQyhwb2lzRkVfVGFibGVWKSkKI3N1bW1hcnkocG9pc0ZFX1RhYmxlVikKCiMgLS0tLS0tLSAgTm93IENvdW50IFJlZ3Jlc3Npb25zIHdpdGggU3VwcGxpZXIgPSBTb3V0aHdhcmssIExhbWJldGgKIyBQb2lzc29uIHdpdGggbm8gZGVuc2l0eQpwb2lzMV9UYWJsZVZfMnN1cHAgPC0gZ2xtKGRlYXRoc19hZGogfiBzdXBwbGllciAKCSsgb2Zmc2V0KGxvZyhwb3ApKSwgZmFtaWx5PXBvaXNzb24sIGRhdGE9cmVnZGF0YV8xODU2Vl8yc3VwcCkKcG9pczFfVGFibGVWXzJzdXBwcm9idXN0c2UgPC0gY29lZnRlc3QocG9pczFfVGFibGVWXzJzdXBwLCB2Y292ID0gdmNvdkhDKHBvaXMxX1RhYmxlVl8yc3VwcCkpCiNzdW1tYXJ5KHBvaXMxX1RhYmxlVl8yc3VwcCkKCiMgUG9pc3NvbiB3aXRoIHllcyBkZW5zaXR5CnBvaXMxcG9wX1RhYmxlVl8yc3VwcCA8LSBnbG0oZGVhdGhzX2FkaiB+IHN1cHBsaWVyICsgZGVuc2l0eV9Tbm93CgkrIG9mZnNldChsb2cocG9wKSksIGZhbWlseT1wb2lzc29uLCBkYXRhPXJlZ2RhdGFfMTg1NlZfMnN1cHApCnBvaXMxcG9wX1RhYmxlVl8yc3VwcHJvYnVzdHNlIDwtIGNvZWZ0ZXN0KHBvaXMxcG9wX1RhYmxlVl8yc3VwcCwgdmNvdiA9IHZjb3ZIQyhwb2lzMXBvcF9UYWJsZVZfMnN1cHApKQojc3VtbWFyeShwb2lzMXBvcF9UYWJsZVZfMnN1cHApCgojIFBvaXNzb24gd2l0aCBGRQpwb2lzRkVfVGFibGVWXzJzdXBwIDwtIGdsbShkZWF0aHNfYWRqIH4gc3VwcGxpZXIgKyBkaXN0cmljdAoJKyBvZmZzZXQobG9nKHBvcCkpLCBmYW1pbHk9cG9pc3NvbiwgZGF0YT1yZWdkYXRhXzE4NTZWXzJzdXBwKQpwb2lzRkVfVGFibGVWXzJzdXBwcm9idXN0c2UgPC0gY29lZnRlc3QocG9pc0ZFX1RhYmxlVl8yc3VwcCwgdmNvdiA9IHZjb3ZIQyhwb2lzRkVfVGFibGVWXzJzdXBwKSkKI3N1bW1hcnkocG9pc0ZFX1RhYmxlVl8yc3VwcCkKCmBgYAoKCiMjIyNOZWdhdGl2ZSBCaW5vbWlhbCBSZWdyZXNzaW9ucwoKVGhlIGZvbGxvd2luZyBjb2RlIGNodW5rIHJ1bnMgTmVnYXRpdmUgQmlub21pYWwgcmVncmVzc2lvbiAoYnV0IGRvZXMgbm90IHByaW50IG91dCByZXN1bHRzKTogYmFzaWMgYW5kIHdpdGggcG9wdWxhdGlvbiBkZW5zaXR5LgoKCmBgYHtyfQojIE5lZ2F0aXZlIEJpbm9taWFsIHdpdGggbm8gZGVuc2l0eQpuYjFfVGFibGVWIDwtIGdsbS5uYihkZWF0aHNfYWRqIH4gc3VwcGxpZXIgCgkrIG9mZnNldChsb2cocG9wKSksIGRhdGEgPSByZWdkYXRhXzE4NTZWXzNzdXBwKQpuYjFfVGFibGVWcm9idXN0c2UgPC0gY29lZnRlc3QobmIxX1RhYmxlViwgdmNvdiA9IHZjb3ZIQyhuYjFfVGFibGVWKSkKI3N1bW1hcnkobmIxX1RhYmxlVikKCiMgTmVnYXRpdmUgQmlub21pYWwgd2l0aCB5ZXMgZGVuc2l0eQpuYjFwb3BfVGFibGVWIDwtIGdsbS5uYihkZWF0aHNfYWRqIH4gc3VwcGxpZXIgKyBkZW5zaXR5X1Nub3cKCSsgb2Zmc2V0KGxvZyhwb3ApKSwgZGF0YSA9IHJlZ2RhdGFfMTg1NlZfM3N1cHApCm5iMXBvcF9UYWJsZVZyb2J1c3RzZSA8LSBjb2VmdGVzdChuYjFwb3BfVGFibGVWLCB2Y292ID0gdmNvdkhDKG5iMXBvcF9UYWJsZVYpKQojc3VtbWFyeShuYjFwb3BfVGFibGVWKQoKIyBOZWdhdGl2ZSBCaW5vbWlhbCB3aXRoIG5vIGRlbnNpdHksIG9ubHkgU291dGh3YXJrIGFuZCBMYW1iZXRoCm5iMV9UYWJsZVZfMnN1cHAgPC0gZ2xtLm5iKGRlYXRoc19hZGogfiBzdXBwbGllciAKCSsgb2Zmc2V0KGxvZyhwb3ApKSwgZGF0YSA9IHJlZ2RhdGFfMTg1NlZfMnN1cHApCm5iMV9UYWJsZVZfMnN1cHByb2J1c3RzZSA8LSBjb2VmdGVzdChuYjFfVGFibGVWXzJzdXBwLCB2Y292ID0gdmNvdkhDKG5iMV9UYWJsZVZfMnN1cHApKQojc3VtbWFyeShuYjFfVGFibGVWXzJzdXBwKQoKIyBOZWdhdGl2ZSBCaW5vbWlhbCB3aXRoIHllcyBkZW5zaXR5LCBvbmx5IFNvdXRod2FyayAmIExhbWJldGgKbmIxcG9wX1RhYmxlVl8yc3VwcCA8LSBnbG0ubmIoZGVhdGhzX2FkaiB+IHN1cHBsaWVyICsgZGVuc2l0eV9Tbm93CgkrIG9mZnNldChsb2cocG9wKSksIGRhdGEgPSByZWdkYXRhXzE4NTZWXzJzdXBwKQpuYjFwb3BfVGFibGVWXzJzdXBwcm9idXN0c2UgPC0gY29lZnRlc3QobmIxcG9wX1RhYmxlVl8yc3VwcCwgdmNvdiA9IHZjb3ZIQyhuYjFwb3BfVGFibGVWXzJzdXBwKSkKI3N1bW1hcnkobmIxcG9wX1RhYmxlVl8yc3VwcCkKCgpgYGAKCgojIyMjVGFibGUgd2l0aCBTdW1tYXJ5CgpUaGUgZm9sbG93aW5nIGNvZGUgY2h1bmsgcG9wdWxhdGVzIGEgdGFibGUgd2l0aCBzdW1tYXJ5IHN0YXRpc3RpY3MgZm9yIHZhcmlvdXMgcmVncmVzc2lvbnM6CgorIFBvaXNzb246IGJhc2ljLCB3aXRoIHBvcHVsYXRpb24gKGhvdXNpbmcpIGRlbnNpdHksIERpc3RyaWN0IEZpeGVkIEVmZmVjdHMKKyBOZWdhdGl2ZSBCaW5vbWlhbDogYmFzaWMsIHdpdGggcG9wdWxhdGlvbiAoaG91c2luZykgZGVuc2l0eQoKYGBge3J9CiMgQ3JlYXRlIHRhYmxlIHdpdGggcmVncmVzc2lvbiByZXN1bHRzIGZvciAxODU0IGJ5IFJlZ2lzdHJhdGlvbiBEaXN0cmljdCAoU291dGh3YXJrICYgTGFtYmV0aCBvbmx5KSAKcmVndGFibGUxODU2VGFibGVWIDwtIG1hdHJpeCgwLG5yb3c9MTYsbmNvbD03KQpjb2xuYW1lcyhyZWd0YWJsZTE4NTZUYWJsZVYpIDwtIGMoIlBvaXNzIiwiUG9pc3MgcG9wIiwiUG9pc3NGRSIsIk5CIiwiTkIgcG9wIiwiTkIgMnN1cHAiLCJOQiBwb3AgMnN1cHAiKQpyb3duYW1lcyhyZWd0YWJsZTE4NTZUYWJsZVYpIDwtIGMoIkxhbWJldGggZWZmZWN0IiwiU0UiLCJ6IHZhbHVlIiwicC12YWx1ZSIsCgkicm9idXN0IFNFIiwieiB2YWx1ZSIsInJhdGlvIGVmZmVjdCIsCgkidGhldGEiLCJyZXNpZCBkZXYiLCJwLXZhbHVlIiwicG9wIGRlbiIsIlNFIiwieiB2YWx1ZSIsIlNvdXRod2FyayBwcmVkIG1vcnQiLAoJIkxhbWJldGggcHJlZCBtb3J0IiwiT3RoZXIgcHJlZCBtb3J0IikKIyBQb3B1bGF0ZSB0aGUgdGFibGUgZnJvbSB0aGUgcmVncmVzc2lvbnMKIyBQb2lzcyBubyBwb3B1bGF0aW9uIGRlbnNpdHkKcmVndGFibGUxODU2VGFibGVWW2MoMSwyLDMsNCksMV0gPC0gc3VtbWFyeShwb2lzMV9UYWJsZVZfMnN1cHApJGNvZWZmaWNpZW50c1syLGMoMSwyLDMsNCldCnJlZ3RhYmxlMTg1NlRhYmxlVltjKDUsNiksMV0gPC0gcG9pczFfVGFibGVWXzJzdXBwcm9idXN0c2VbMixjKDIsMyldCnJlZ3RhYmxlMTg1NlRhYmxlVls3LDFdIDwtIGV4cCgtcmVndGFibGUxODU2VGFibGVWWzEsMV0pCnJlZ3RhYmxlMTg1NlRhYmxlVls5LDFdIDwtIHN1bW1hcnkocG9pczFfVGFibGVWXzJzdXBwKSRkZXZpYW5jZQpyZWd0YWJsZTE4NTZUYWJsZVZbMTAsMV0gPC0gMSAtIHBjaGlzcShwb2lzMV9UYWJsZVZfMnN1cHAkZGV2aWFuY2UscG9pczFfVGFibGVWXzJzdXBwJGRmLnJlc2lkdWFsKQpyZWd0YWJsZTE4NTZUYWJsZVZbMTQsMV0gPC0gMTAwMDAgKiBzdW0ocG9pczFfVGFibGVWXzJzdXBwJGZpdHRlZC52YWx1ZXNbMTo5XSkgLyBzdW0ocmVnZGF0YV8xODU2Vl8zc3VwcCRwb3BbMTo5XSkKcmVndGFibGUxODU2VGFibGVWWzE1LDFdIDwtIDEwMDAwICogc3VtKHBvaXMxX1RhYmxlVl8yc3VwcCRmaXR0ZWQudmFsdWVzWzEwOjE2XSkgLyBzdW0ocmVnZGF0YV8xODU2Vl8zc3VwcCRwb3BbMTA6MTZdKQojcmVndGFibGUxODU2VGFibGVWWzE2LDFdIDwtIDEwMDAwICogc3VtKHBvaXMxX1RhYmxlVl8yc3VwcCRmaXR0ZWQudmFsdWVzWzE3OjIyXSkgLyBzdW0ocmVnZGF0YV8xODU2Vl8zc3VwcCRwb3BbMTc6MjJdKQojIFBvaXNzIHllcyBwb3B1bGF0aW9uIGRlbnNpdHkKcmVndGFibGUxODU2VGFibGVWW2MoMSwyLDMsNCksMl0gPC0gc3VtbWFyeShwb2lzMXBvcF9UYWJsZVZfMnN1cHApJGNvZWZmaWNpZW50c1syLGMoMSwyLDMsNCldCnJlZ3RhYmxlMTg1NlRhYmxlVltjKDUsNiksMl0gPC0gcG9pczFwb3BfVGFibGVWXzJzdXBwcm9idXN0c2VbMixjKDIsMyldCnJlZ3RhYmxlMTg1NlRhYmxlVls3LDJdIDwtIGV4cCgtcmVndGFibGUxODU2VGFibGVWWzEsMl0pCnJlZ3RhYmxlMTg1NlRhYmxlVltjKDExLDEyLDEzKSwyXSA8LSBzdW1tYXJ5KHBvaXMxcG9wX1RhYmxlVl8yc3VwcCkkY29lZmZpY2llbnRzWzMsYygxLDIsMyldCnJlZ3RhYmxlMTg1NlRhYmxlVls5LDJdIDwtIHN1bW1hcnkocG9pczFwb3BfVGFibGVWXzJzdXBwKSRkZXZpYW5jZQpyZWd0YWJsZTE4NTZUYWJsZVZbMTAsMl0gPC0gMSAtIHBjaGlzcShwb2lzMXBvcF9UYWJsZVZfMnN1cHAkZGV2aWFuY2UscG9pczFwb3BfVGFibGVWXzJzdXBwJGRmLnJlc2lkdWFsKQpyZWd0YWJsZTE4NTZUYWJsZVZbMTQsMl0gPC0gMTAwMDAgKiBzdW0ocG9pczFwb3BfVGFibGVWXzJzdXBwJGZpdHRlZC52YWx1ZXNbMTo5XSkgLyBzdW0ocmVnZGF0YV8xODU2Vl8zc3VwcCRwb3BbMTo5XSkKcmVndGFibGUxODU2VGFibGVWWzE1LDJdIDwtIDEwMDAwICogc3VtKHBvaXMxcG9wX1RhYmxlVl8yc3VwcCRmaXR0ZWQudmFsdWVzWzEwOjE2XSkgLyBzdW0ocmVnZGF0YV8xODU2Vl8zc3VwcCRwb3BbMTA6MTZdKQojcmVndGFibGUxODU2VGFibGVWWzE2LDJdIDwtIDEwMDAwICogc3VtKHBvaXMxcG9wX1RhYmxlVl8yc3VwcCRmaXR0ZWQudmFsdWVzWzE3OjIyXSkgLyBzdW0ocmVnZGF0YV8xODU2Vl8zc3VwcCRwb3BbMTc6MjJdKQojIFBvaXNzIEZFCnJlZ3RhYmxlMTg1NlRhYmxlVltjKDEsMiwzLDQpLDNdIDwtIHN1bW1hcnkocG9pc0ZFX1RhYmxlVl8yc3VwcCkkY29lZmZpY2llbnRzWzIsYygxLDIsMyw0KV0KcmVndGFibGUxODU2VGFibGVWW2MoNSw2KSwzXSA8LSBwb2lzRkVfVGFibGVWXzJzdXBwcm9idXN0c2VbMixjKDIsMyldCnJlZ3RhYmxlMTg1NlRhYmxlVls3LDNdIDwtIGV4cCgtcmVndGFibGUxODU2VGFibGVWWzEsM10pCnJlZ3RhYmxlMTg1NlRhYmxlVls5LDNdIDwtIHN1bW1hcnkocG9pc0ZFX1RhYmxlVl8yc3VwcCkkZGV2aWFuY2UKcmVndGFibGUxODU2VGFibGVWWzEwLDNdIDwtIDEgLSBwY2hpc3EocG9pc0ZFX1RhYmxlVl8yc3VwcCRkZXZpYW5jZSxwb2lzRkVfVGFibGVWXzJzdXBwJGRmLnJlc2lkdWFsKQpyZWd0YWJsZTE4NTZUYWJsZVZbMTQsM10gPC0gMTAwMDAgKiBzdW0ocG9pc0ZFX1RhYmxlVl8yc3VwcCRmaXR0ZWQudmFsdWVzWzE6OV0pIC8gc3VtKHJlZ2RhdGFfMTg1NlZfM3N1cHAkcG9wWzE6OV0pCnJlZ3RhYmxlMTg1NlRhYmxlVlsxNSwzXSA8LSAxMDAwMCAqIHN1bShwb2lzRkVfVGFibGVWXzJzdXBwJGZpdHRlZC52YWx1ZXNbMTA6MTZdKSAvIHN1bShyZWdkYXRhXzE4NTZWXzNzdXBwJHBvcFsxMDoxNl0pCiNyZWd0YWJsZTE4NTZUYWJsZVZbMTYsM10gPC0gMTAwMDAgKiBzdW0ocG9pc0ZFX1RhYmxlVl8yc3VwcCRmaXR0ZWQudmFsdWVzWzE3OjIyXSkgLyBzdW0ocmVnZGF0YV8xODU2Vl8zc3VwcCRwb3BbMTc6MjJdKQojIE5lZyBCaW5vbSBubyBwb3B1bGF0aW9uIGRlbnNpdHkKcmVndGFibGUxODU2VGFibGVWW2MoMSwyLDMsNCksNF0gPC0gc3VtbWFyeShuYjFfVGFibGVWKSRjb2VmZmljaWVudHNbMixjKDEsMiwzLDQpXQpyZWd0YWJsZTE4NTZUYWJsZVZbYyg1LDYpLDRdIDwtIG5iMV9UYWJsZVZyb2J1c3RzZVsyLGMoMiwzKV0KcmVndGFibGUxODU2VGFibGVWWzcsNF0gPC0gZXhwKC1yZWd0YWJsZTE4NTZUYWJsZVZbMSw0XSkKcmVndGFibGUxODU2VGFibGVWWzgsNF0gPC0gc3VtbWFyeShuYjFfVGFibGVWKSR0aGV0YQpyZWd0YWJsZTE4NTZUYWJsZVZbOSw0XSA8LSBzdW1tYXJ5KG5iMV9UYWJsZVYpJGRldmlhbmNlCnJlZ3RhYmxlMTg1NlRhYmxlVlsxMCw0XSA8LSAxIC0gcGNoaXNxKG5iMV9UYWJsZVYkZGV2aWFuY2UsbmIxX1RhYmxlViRkZi5yZXNpZHVhbCkKcmVndGFibGUxODU2VGFibGVWWzE0LDRdIDwtIDEwMDAwICogc3VtKG5iMV9UYWJsZVYkZml0dGVkLnZhbHVlc1sxOjldKSAvIHN1bShyZWdkYXRhXzE4NTZWXzNzdXBwJHBvcFsxOjldKQpyZWd0YWJsZTE4NTZUYWJsZVZbMTUsNF0gPC0gMTAwMDAgKiBzdW0obmIxX1RhYmxlViRmaXR0ZWQudmFsdWVzWzEwOjE2XSkgLyBzdW0ocmVnZGF0YV8xODU2Vl8zc3VwcCRwb3BbMTA6MTZdKQpyZWd0YWJsZTE4NTZUYWJsZVZbMTYsNF0gPC0gMTAwMDAgKiBzdW0obmIxX1RhYmxlViRmaXR0ZWQudmFsdWVzWzE3OjIyXSkgLyBzdW0ocmVnZGF0YV8xODU2Vl8zc3VwcCRwb3BbMTc6MjJdKQojIE5lZyBCaW5vbSB5ZXMgcG9wdWxhdGlvbiBkZW5zaXR5CnJlZ3RhYmxlMTg1NlRhYmxlVltjKDEsMiwzLDQpLDVdIDwtIHN1bW1hcnkobmIxcG9wX1RhYmxlVikkY29lZmZpY2llbnRzWzIsYygxLDIsMyw0KV0KcmVndGFibGUxODU2VGFibGVWW2MoNSw2KSw1XSA8LSBuYjFwb3BfVGFibGVWcm9idXN0c2VbMixjKDIsMyldCnJlZ3RhYmxlMTg1NlRhYmxlVls3LDVdIDwtIGV4cCgtcmVndGFibGUxODU2VGFibGVWWzEsNV0pCnJlZ3RhYmxlMTg1NlRhYmxlVls4LDVdIDwtIHN1bW1hcnkobmIxcG9wX1RhYmxlVikkdGhldGEKcmVndGFibGUxODU2VGFibGVWW2MoMTEsMTIsMTMpLDVdIDwtIHN1bW1hcnkobmIxcG9wX1RhYmxlVikkY29lZmZpY2llbnRzWzQsYygxLDIsMyldCnJlZ3RhYmxlMTg1NlRhYmxlVls5LDVdIDwtIHN1bW1hcnkobmIxcG9wX1RhYmxlVikkZGV2aWFuY2UKcmVndGFibGUxODU2VGFibGVWWzEwLDVdIDwtIDEgLSBwY2hpc3EobmIxcG9wX1RhYmxlViRkZXZpYW5jZSxuYjFwb3BfVGFibGVWJGRmLnJlc2lkdWFsKQpyZWd0YWJsZTE4NTZUYWJsZVZbMTQsNV0gPC0gMTAwMDAgKiBzdW0obmIxcG9wX1RhYmxlViRmaXR0ZWQudmFsdWVzWzE6OV0pIC8gc3VtKHJlZ2RhdGFfMTg1NlZfM3N1cHAkcG9wWzE6OV0pCnJlZ3RhYmxlMTg1NlRhYmxlVlsxNSw1XSA8LSAxMDAwMCAqIHN1bShuYjFwb3BfVGFibGVWJGZpdHRlZC52YWx1ZXNbMTA6MTZdKSAvIHN1bShyZWdkYXRhXzE4NTZWXzNzdXBwJHBvcFsxMDoxNl0pCnJlZ3RhYmxlMTg1NlRhYmxlVlsxNiw1XSA8LSAxMDAwMCAqIHN1bShuYjFwb3BfVGFibGVWJGZpdHRlZC52YWx1ZXNbMTc6MjJdKSAvIHN1bShyZWdkYXRhXzE4NTZWXzNzdXBwJHBvcFsxNzoyMl0pCiMgTmVnIEJpbm9tIG5vIHBvcHVsYXRpb24gZGVuc2l0eSwgMiBzdXBwbGllcnMgKFNvdXRod2FyayBhbmQgTGFtYmV0aCBvbmx5KQpyZWd0YWJsZTE4NTZUYWJsZVZbYygxLDIsMyw0KSw2XSA8LSBzdW1tYXJ5KG5iMV9UYWJsZVZfMnN1cHApJGNvZWZmaWNpZW50c1syLGMoMSwyLDMsNCldCnJlZ3RhYmxlMTg1NlRhYmxlVltjKDUsNiksNl0gPC0gbmIxX1RhYmxlVl8yc3VwcHJvYnVzdHNlWzIsYygyLDMpXQpyZWd0YWJsZTE4NTZUYWJsZVZbNyw2XSA8LSBleHAoLXJlZ3RhYmxlMTg1NlRhYmxlVlsxLDZdKQpyZWd0YWJsZTE4NTZUYWJsZVZbOCw2XSA8LSBzdW1tYXJ5KG5iMV9UYWJsZVZfMnN1cHApJHRoZXRhCnJlZ3RhYmxlMTg1NlRhYmxlVls5LDZdIDwtIHN1bW1hcnkobmIxX1RhYmxlVl8yc3VwcCkkZGV2aWFuY2UKcmVndGFibGUxODU2VGFibGVWWzEwLDZdIDwtIDEgLSBwY2hpc3EobmIxX1RhYmxlVl8yc3VwcCRkZXZpYW5jZSxuYjFfVGFibGVWXzJzdXBwJGRmLnJlc2lkdWFsKQpyZWd0YWJsZTE4NTZUYWJsZVZbMTQsNl0gPC0gMTAwMDAgKiBzdW0obmIxX1RhYmxlVl8yc3VwcCRmaXR0ZWQudmFsdWVzWzE6OV0pIC8gc3VtKHJlZ2RhdGFfMTg1NlZfM3N1cHAkcG9wWzE6OV0pCnJlZ3RhYmxlMTg1NlRhYmxlVlsxNSw2XSA8LSAxMDAwMCAqIHN1bShuYjFfVGFibGVWXzJzdXBwJGZpdHRlZC52YWx1ZXNbMTA6MTZdKSAvIHN1bShyZWdkYXRhXzE4NTZWXzNzdXBwJHBvcFsxMDoxNl0pCiMgTmVnIEJpbm9tIHllcyBwb3B1bGF0aW9uIGRlbnNpdHksIDIgc3VwcGxpZXJzIChTb3V0aHdhcmsgYW5kIExhbWJldGggb25seSkKcmVndGFibGUxODU2VGFibGVWW2MoMSwyLDMsNCksN10gPC0gc3VtbWFyeShuYjFwb3BfVGFibGVWXzJzdXBwKSRjb2VmZmljaWVudHNbMixjKDEsMiwzLDQpXQpyZWd0YWJsZTE4NTZUYWJsZVZbYyg1LDYpLDddIDwtIG5iMXBvcF9UYWJsZVZfMnN1cHByb2J1c3RzZVsyLGMoMiwzKV0KcmVndGFibGUxODU2VGFibGVWWzcsN10gPC0gZXhwKC1yZWd0YWJsZTE4NTZUYWJsZVZbMSw3XSkKcmVndGFibGUxODU2VGFibGVWWzgsN10gPC0gc3VtbWFyeShuYjFwb3BfVGFibGVWXzJzdXBwKSR0aGV0YQpyZWd0YWJsZTE4NTZUYWJsZVZbYygxMSwxMiwxMyksN10gPC0gc3VtbWFyeShuYjFwb3BfVGFibGVWXzJzdXBwKSRjb2VmZmljaWVudHNbMyxjKDEsMiwzKV0KcmVndGFibGUxODU2VGFibGVWWzksN10gPC0gc3VtbWFyeShuYjFwb3BfVGFibGVWXzJzdXBwKSRkZXZpYW5jZQpyZWd0YWJsZTE4NTZUYWJsZVZbMTAsN10gPC0gMSAtIHBjaGlzcShuYjFwb3BfVGFibGVWXzJzdXBwJGRldmlhbmNlLG5iMXBvcF9UYWJsZVZfMnN1cHAkZGYucmVzaWR1YWwpCnJlZ3RhYmxlMTg1NlRhYmxlVlsxNCw3XSA8LSAxMDAwMCAqIHN1bShuYjFwb3BfVGFibGVWXzJzdXBwJGZpdHRlZC52YWx1ZXNbMTo5XSkgLyBzdW0ocmVnZGF0YV8xODU2Vl8zc3VwcCRwb3BbMTo5XSkKcmVndGFibGUxODU2VGFibGVWWzE1LDddIDwtIDEwMDAwICogc3VtKG5iMXBvcF9UYWJsZVZfMnN1cHAkZml0dGVkLnZhbHVlc1sxMDoxNl0pIC8gc3VtKHJlZ2RhdGFfMTg1NlZfM3N1cHAkcG9wWzEwOjE2XSkKCmthYmxlKHJlZ3RhYmxlMTg1NlRhYmxlVltjKDEsMiwzLDUsNiw3LDgsOSwxMCwxMSwxMiwxMywxNCwxNSwxNiksYygxLDMsNiw3KV0sZGlnaXRzPTMsIGNhcHRpb24gPSAiU3VtbWFyeSAtIFF1YXNpLVJhbmRvbWl6ZWQgUmVncmVzc2lvbnMsIDE4NTYgVGFibGUgViAoYnkgRGlzdHJpY3QsIGZ1bGwgMTg1NCBlcGlkZW1pYykiLGZvcm1hdD0ncGFuZG9jJykKCgpgYGAKCiMjIyNDb25jbHVzaW9uCgpJIGFtIG5vdCBwcmludGluZyBvdXQgYWxsIHRoZSByZWdyZXNzaW9ucyAoeW91IGNhbiBjaGVjayB0aGUgc3VtbWFyeSBzdGF0aXN0aWNzIGluIHRoZSB0YWJsZSksIGJ1dCB0aGUgcmVzdWx0cyBhcmUgYnJvYWRseSB0aGUgc2FtZSBhcyBmb3IgdGhlIGZpcnN0IHNldmVuIHdlZWtzOgoKKyBTaW1wbGUgUG9pc3NvbiBoYXMgYSBoaWdoIFJlc2lkdWFsIERldmlhbmNlLCBpbXBseWluZyB0aGF0IFBvaXNzb24gZG9lcyBub3QgZml0IHRoZSBkYXRhIHdlbGwgLSBhbmQgdGhhdCB0aGUgZXN0aW1hdGVkIHN0YW5kYXJkIGVycm9ycyBhcmUgdG9vIHNtYWxsLgorIEluY2x1ZGluZyBwb3B1bGF0aW9uIChob3VzaW5nKSBkZW5zaXR5IHNob3dzIGRlbnNpdHkgaGFzIGEgbmVnbGlnaWJsZSBlZmZlY3QKKyBJbmNsdWRpbmcgc3ViLWRpc3RyaWN0IGZpeGVkIGVmZmVjdHMgZG9lcyBub3QgcmVkdWNlIHRoZSBSZXNpZHVhbCBEZXZpYW5jZSBlbm91Z2ggdG8gZml0IHRoZSBkYXRhLiAKKyBOZWdhdGl2ZSBCaW5vbWlhbCBmaXRzIHRoZSBkYXRhIHNsaWdodGx5IGJldHRlciAoaW4gdGVybXMgb2YgUmVzaWR1YWwgRGV2aWFuY2UgLSBpdCBpcyBtYXJnaW5hbGx5IHNtYWxsIGVub3VnaCkuIAorIEluIGFsbCBjYXNlcyB0aGUgIkxhbWJldGggRWZmZWN0IiBpcyBsYXJnZSAtIChyb3VnaGx5IGByIHJvdW5kKG5iMXBvcF9UYWJsZVYkY29lZmZpY2llbnRzWzJdLDEpYCBmb3IgYSByYXRpbyBlZmZlY3Qgb2YgYHIgcm91bmQoZXhwKC1uYjFwb3BfVGFibGVWJGNvZWZmaWNpZW50c1syXSksMSlgKSAKKyBUaGUgIkxhbWJldGggRWZmZWN0IiBpcyBzdGF0aXN0aWNhbGx5IHNpZ25pZmljYW50IChoYXMgYSB2ZXJ5IGxhcmdlIHotdmFsdWUpLiBXZSBjYW5ub3QgcmVseSBvbiB0aGUgei12YWx1ZSBmb3IgdGhlIGJhc2ljIFBvaXNzb24gcmVncmVzc2lvbiAoYmVjYXVzZSB0aGUgbW9kZWwgZG9lcyBub3QgZml0IHdlbGwgLSB0aGUgUmVzaWR1YWwgRGV2aWFuY2UgaXMgbGFyZ2UpLCBhbmQgd2Ugd2FudCB0byBiZSBjYXV0aW91cyB3aXRoIGFsbCB0aGVzZSBtb2RlbHMuIEV2ZW4gdXNpbmcgcm9idXN0IHN0YW5kYXJkIGVycm9ycywgaG93ZXZlciwgd2UgZmluZCB6LXZhbHVlcyBvZiA1IG9yIGxhcmdlci4gCgoKIyMjT3ZlcmFsbCBDb25jbHVzaW9uCgpTbm93IHJlY29nbml6ZWQgdGhlIHZhbHVlIG9mIGhpcyAiR3JhbmQgRXhwZXJpbWVudCIgLSB0aGUgbmVhci1yYW5kb21pemF0aW9uIG9mIGN1c3RvbWVycyBpbiBTb3V0aCBMb25kb24uIEluIGhpcyAxODU1ICJPbiB0aGUgbW9kZSAuLi4iIGhlIGRpZCBub3QgaGF2ZSB0aGUgcG9wdWxhdGlvbiBkYXRhIHRvIHRlc3QgY2FyZWZ1bGx5LCBhbmQgd2l0aCB0aGUgcG9wdWxhdGlvbiBkYXRhIGluIGhpcyAxODU2ICJDaG9sZXJhIGFuZCB0aGUgd2F0ZXIgc3VwcGx5IC4uLiIgaGUgZGlkIG5vdCBoYXZlIHRoZSBzdGF0aXN0aWNhbCBmcmFtZXdvcmsgb3IgdGhlIHRvb2xzIGZvciBmb3JtYWwgaHlwb3RoZXNpcyB0ZXN0aW5nLiAKCldlLCBob3dldmVyLCBkbyBoYXZlIHRoZSBuZWNlc3NhcnkgZnJhbWV3b3JrIGFuZCB0b29scy4gV2hldGhlciB1c2luZyB0aGUgZmlyc3Qgc2V2ZW4gd2Vla3MgYnkgc3ViLWRpc3RyaWN0IGZyb20gMTg1NSBUYWJsZSBWSUlJIG9yIHRoZSBmdWxsIDE4NTQgb3V0YnJlYWsgYnkgRGlzdHJpY3QgZnJvbSAxODU2IFRhYmxlIFYsIHRoZSByZXN1bHRzIGFyZSB1bmFtYmlndW91czogY3VzdG9tZXJzIHN1cHBsaWVkIHdpdGggY2xlYW4gd2F0ZXIgYnkgdGhlIExhbWJldGggQ28uIGhhZCBkcmFtYXRpY2FsbHkgbG93ZXIgbW9ydGFsaXR5IHRoYW4gY3VzdG9tZXJzIHN1cHBsaWVkIGJ5IHRoZSBTb3V0aHdhcmsgJiBWYXV4aGFsbCBDby4gKG9yIHN1cHBsaWVkIGJ5ICJPdGhlciIpLiBTbm93IHJlY29nbml6ZWQgdGhhdCB0aGUgbWl4aW5nIG9mIGN1c3RvbWVycyB3YXMgYSBzdHJvbmcgYXJndW1lbnQgdGhhdCBydWxlZCBvdXQgdmlydHVhbGx5IGFsbCBvdGhlciBjb25mb3VuZGluZyBmYWN0b3JzIC0gaW5jb21lLCBzZXgsIGFnZSwgc29jaWFsIHN0YXR1cywgd2VhdGhlciAtIHNpbmNlIGN1c3RvbWVycyB0aGF0IHdlcmUgcmFuZG9tbHkgbWl4ZWQgYW5kIGluIGNsb3NlIHByb3hpbWl0eSB3b3VsZCBlaXRoZXIgYmUgbWl4ZWQgYWNyb3NzIHRoZXNlIHZhcmlhYmxlcyBvciB3b3VsZCBzaGFyZSB0aGUgc2FtZSBpbmZsdWVuY2UgKHdlYXRoZXIsIGZvciBleGFtcGxlKS4gV2l0aCBvdXIgc3RhdGlzdGljYWwgdG9vbHMgd2UgY2FuIG1vcmUgZm9ybWFsbHkgY29uZmlybSB3aGF0IFNub3cgc2F3IGluIHRoZSBkYXRhIC0gY2xlYW4gd2F0ZXIgd2FzIG1vcmUgaW1wb3J0YW50IHRoYW4gYW55IG9mIHRoZSBvdGhlciBmYWN0b3JzIGhlIChvciB3ZSkgY291bGQgdGhpbmsgb2YuIAoK