Introduction
This is the first, introductory notebook for my John Snow project. This sheet reads in selected data from John Snow 1855, “On the mode of communication of cholera”, (data from the .pdf at http://archive.org/details/b28985266 ) and performs some simple cross-checking: comparing row-sums against Snow’s reported totals.
The four tables I use from Snow 1855 are:
Table VII: 1854 p 84: deaths by Sub-District, four weeks ending 5th August. Categorized by source (Southwark & Vauxhall; Lambeth; Pump-wells; River Thames, ditches, etc.; Unascertained) categorization carefully performed by Snow
Table VIII p 85: deaths by Sub-District, seven weeks ending 26th August. Categorized by source (Southwark & Vauxhall; Lambeth; Pump-wells; River Thames, ditches, etc.; Unascertained) categorization carefully performed by Snow
Table IX p. 86: The Southwark & Vauxhall vs Lambeth comparison (quasi-randomized trial). Displays number of houses, a summary of Table VIII (plus additional for “Rest of London”), and calculated mortality rates per household
Table XII p. 90: Deaths 1849 & 1854 by sub-district. For 1854 through October 21 (versus through August 26 for Table VIII)
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
#
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="#")
tableix <- read.csv(file="Snow1855_TableIX.csv", header=TRUE, sep=",", skip=5,comment.char="#")
tablexii <- read.csv(file="Snow1855_TableXII.csv", header=TRUE, sep=",", skip=5,comment.char="#")
These tables are “data frame” (See https://www.r-bloggers.com/15-easy-solutions-to-your-data-frame-problems-in-r/ for tutorial on data frames). For dataframes subsetting is easy.
class(tablexii)
[1] "data.frame"
subset(tableviii,supplier=="Lambeth")
Check Table VII. Snow’s published tables show the total in the last row for each column, so the sum of all rows should be twice the last row. The following checks this and all results should be zero.
colSums(tablevii[,2:8]) - 2*tablevii[nrow(tablevii),2:8]
Check Table VIII. Again, the sum of all rows should be twice the last row. The following should be zero.
colSums(tableviii[,2:8]) - 2*tableviii[nrow(tableviii),2:8]
We can check the population sub-totals in Table VIII (for “first 12”, “next 16” and last (Lambeth-only) sub-districts) against the population sub-totals shown in Table VI (p. 73). (Note that Table VI shows only three of the four Lambeth sub-districts - excludes Sydenham). The sub-totals in Table VI are:
- First 12 (Southwark & Vauxhall) 167,654
- Next 16 (joint Southwark & Vauxhall and Lambeth) 301,149
- This seems to be a typo in Snow’s Table VI and should read 300,149 so the comparison will be off by 1,000
- Last 3 (Lambeth excluding Sydenham) 14,632
- Sydenham is 4,501 so the comparison will be off by this amount
x1 <- c(sum(subset(tableviii,supplier=="SouthwarkVauxhall")[,2]),
sum(subset(tableviii,supplier=="SouthwarkVauxhall_Lambeth")[,2]),
sum(subset(tableviii,supplier=="Lambeth")[,2]))
x1 - c(167654, 301149, 14632)
[1] 0 -1000 4501
Table XII has deaths for 1849 and 1854 by sub-district. We can check as follows:
- Subset by “SouthwarkVauxhall”, “SouthwarkVauxhall_Lambeth”, “Lambeth” to get the “first 12”, “next 16”, and “final 4” sub-districts
- Sum over these subsets
- Snow reports these sub-totals in the last three rows of Table XII
- The following check will show zeros when the sums over the sub-setted data equal the reported sub-totals
xcomp <- matrix(data=0,nrow=3,ncol=2)
colnames(xcomp) <- c("deaths1849","deaths1854")
rownames(xcomp) <- c("first12","next16","last4")
xcomp <- as.data.frame(xcomp)
x1 <- subset(tablexii,supplier=="SouthwarkVauxhall")
x2 <- colSums(x1[,2:3])
x3 <- subset(tablexii,supplier=="first12")
xcomp[1,] <- x2-x3[2:3]
x1 <- subset(tablexii,supplier=="SouthwarkVauxhall_Lambeth")
x2 <- colSums(x1[,2:3])
x3 <- subset(tablexii,supplier=="next16")
#print("Death sub-total for SouthwarkVauxhall & Lambeth checked against Snow's subtotal (should be zero)")
xcomp[2,] <- x2-x3[2:3]
x1 <- subset(tablexii,supplier=="Lambeth")
x2 <- colSums(x1[,2:3])
x3 <- subset(tablexii,supplier=="last4")
#print("Death sub-total for Lambeth checked against Snow's subtotal (should be zero)")
xcomp[3,] <- x2-x3[2:3]
xcomp
tablevii
tableviii
tableix
tablexii
LS0tCnRpdGxlOiAiSm9obiBTbm93IFByb2plY3Q6IFJlYWRpbmcgYW5kIGNyb3NzLWNoZWNraW5nIDE4NTUiCmF1dGhvcjogIltUaG9tYXMgQ29sZW1hbl0oaHR0cDovL3d3dy5oaWxlcnVuLm9yZy9lY29uKSIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMjIyBTZWUgIkNhdXNhbGl0eSBpbiB0aGUgVGltZSBvZiBDaG9sZXJhIiB3b3JraW5nIHBhcGVyIGF0IGh0dHBzOi8vcGFwZXJzLnNzcm4uY29tL2Fic3RyYWN0PTMyNjIyMzQgYW5kIG15IFtKb2huIFNub3cgcHJvamVjdCB3ZWJzaXRlXShodHRwOi8vd3d3LmhpbGVydW4ub3JnL2Vjb24vcGFwZXJzL3Nub3cpCgojIyMjIFRoaXMgbm90ZWJvb2sgaXMgbGljZW5zZWQgdW5kZXIgdGhlIFtCU0QgMi1DbGF1c2UgTGljZW5zZV0oaHR0cHM6Ly9vcGVuc291cmNlLm9yZy9saWNlbnNlcy9CU0QtMi1DbGF1c2UpCgojIyMgSW50cm9kdWN0aW9uCgpUaGlzIGlzIHRoZSBmaXJzdCwgaW50cm9kdWN0b3J5IG5vdGVib29rIGZvciBteSBbSm9obiBTbm93IHByb2plY3RdKGh0dHA6Ly93d3cuaGlsZXJ1bi5vcmcvZWNvbi9wYXBlcnMvc25vdykuIFRoaXMgc2hlZXQgcmVhZHMgaW4gc2VsZWN0ZWQgZGF0YSBmcm9tIEpvaG4gU25vdyAxODU1LCAiT24gdGhlIG1vZGUgb2YgY29tbXVuaWNhdGlvbiBvZiBjaG9sZXJhIiwgKGRhdGEgZnJvbSB0aGUgLnBkZiBhdCBodHRwOi8vYXJjaGl2ZS5vcmcvZGV0YWlscy9iMjg5ODUyNjYgKSBhbmQgcGVyZm9ybXMgc29tZSBzaW1wbGUgY3Jvc3MtY2hlY2tpbmc6IGNvbXBhcmluZyByb3ctc3VtcyBhZ2FpbnN0IFNub3cncyByZXBvcnRlZCB0b3RhbHMuIAoKVGhlIGZvdXIgdGFibGVzIEkgdXNlIGZyb20gU25vdyAxODU1IGFyZToKCiogVGFibGUgVklJOiAxODU0IHAgODQ6IGRlYXRocyBieSBTdWItRGlzdHJpY3QsIGZvdXIgd2Vla3MgZW5kaW5nIDV0aCBBdWd1c3QuIENhdGVnb3JpemVkIGJ5IHNvdXJjZSAoU291dGh3YXJrICYgVmF1eGhhbGw7IExhbWJldGg7IFB1bXAtd2VsbHM7IFJpdmVyIFRoYW1lcywgZGl0Y2hlcywgZXRjLjsgVW5hc2NlcnRhaW5lZCkgY2F0ZWdvcml6YXRpb24gY2FyZWZ1bGx5IHBlcmZvcm1lZCBieSBTbm93CgoqIFRhYmxlIFZJSUkgcCA4NTogZGVhdGhzIGJ5IFN1Yi1EaXN0cmljdCwgc2V2ZW4gd2Vla3MgZW5kaW5nIDI2dGggQXVndXN0LiBDYXRlZ29yaXplZCBieSBzb3VyY2UgKFNvdXRod2FyayAmIFZhdXhoYWxsOyBMYW1iZXRoOyBQdW1wLXdlbGxzOyBSaXZlciBUaGFtZXMsIGRpdGNoZXMsIGV0Yy47IFVuYXNjZXJ0YWluZWQpIGNhdGVnb3JpemF0aW9uIGNhcmVmdWxseSBwZXJmb3JtZWQgYnkgU25vdwoKKiBUYWJsZSBJWCBwLiA4NjogVGhlIFNvdXRod2FyayAmIFZhdXhoYWxsIHZzIExhbWJldGggY29tcGFyaXNvbiAocXVhc2ktcmFuZG9taXplZCB0cmlhbCkuIERpc3BsYXlzIG51bWJlciBvZiBob3VzZXMsIGEgc3VtbWFyeSBvZiBUYWJsZSBWSUlJIChwbHVzIGFkZGl0aW9uYWwgZm9yICJSZXN0IG9mIExvbmRvbiIpLCBhbmQgY2FsY3VsYXRlZCBtb3J0YWxpdHkgcmF0ZXMgcGVyIGhvdXNlaG9sZAoKKiBUYWJsZSBYSUkgcC4gOTA6IERlYXRocyAxODQ5ICYgMTg1NCBieSBzdWItZGlzdHJpY3QuIEZvciAxODU0IHRocm91Z2ggT2N0b2JlciAyMSAodmVyc3VzIHRocm91Z2ggQXVndXN0IDI2IGZvciBUYWJsZSBWSUlJKQoKRm9yIGEgYnJpZWYgaW50cm9kdWN0aW9uIHRvIFNub3cncyB3b3JrLCBzZWU6CgorICoqU25vdydzIG9yaWdpbmFsIDE4NTUgbW9ub2dyYXBoKiogKGl0IGlzIG1hc3RlcmZ1bCk6IFNub3csIEpvaG4uIDE4NTUuICpPbiB0aGUgTW9kZSBvZiBDb21tdW5pY2F0aW9uIG9mIENob2xlcmEqLiAybmQgZWQuIExvbmRvbjogSm9obiBDaHVyY2hpbGwuIGh0dHA6Ly9hcmNoaXZlLm9yZy9kZXRhaWxzL2IyODk4NTI2Ni4KKyAqKlRoZSBiZXN0IHBvcHVsYXIgZXhwb3NpdGlvbiBJIGhhdmUgZm91bmQqKjogSm9obnNvbiwgU3RldmVuLiAyMDA3LiAqVGhlIEdob3N0IE1hcDogVGhlIFN0b3J5IG9mIExvbmRvbuKAmXMgTW9zdCBUZXJyaWZ5aW5nIEVwaWRlbWljLS1hbmQgSG93IEl0IENoYW5nZWQgU2NpZW5jZSwgQ2l0aWVzLCBhbmQgdGhlIE1vZGVybiBXb3JsZCouIFJlcHJpbnQgZWRpdGlvbi4gTmV3IFlvcms6IFJpdmVyaGVhZCBCb29rcy4KKyAqKkFub3RoZXIgZ29vZCBwb3B1bGFyIHZlcnNpb24qKjogSGVtcGVsLCBTYW5kcmEuIDIwMDcuICpUaGUgU3RyYW5nZSBDYXNlIG9mIHRoZSBCcm9hZCBTdHJlZXQgUHVtcDogSm9obiBTbm93IGFuZCB0aGUgTXlzdGVyeSBvZiBDaG9sZXJhKi4gRmlyc3QgZWRpdGlvbi4gQmVya2VsZXk6IFVuaXZlcnNpdHkgb2YgQ2FsaWZvcm5pYSBQcmVzcy4KKyAqKlR1ZnRlJ3MgY2xhc3NpYyBkaXNjdXNzaW9uIG9mIFNub3cncyBtYXBwaW5nKiogKGEgdG9waWMgSSBkb24ndCBjb3ZlciBoZXJlKTogVHVmdGUsIEVkd2FyZCBSLiAxOTk3LiAqVmlzdWFsIEV4cGxhbmF0aW9uczogSW1hZ2VzIGFuZCBRdWFudGl0aWVzLCBFdmlkZW5jZSBhbmQgTmFycmF0aXZlKi4gMXN0IGVkaXRpb24uIEdyYXBoaWNzIFByZXNzLgorICoqQmlvZ3JhcGh5Kio6IFZpbnRlbi1Kb2hhbnNlbiwgUGV0ZXIsIEhvd2FyZCBCcm9keSwgTmlnZWwgUGFuZXRoLCBTdGVwaGVuIFJhY2htYW4sIGFuZCBNaWNoYWVsIFJ1c3NlbGwgUmlwLiAyMDAzLiAqQ2hvbGVyYSwgQ2hsb3JvZm9ybSBhbmQgdGhlIFNjaWVuY2Ugb2YgTWVkaWNpbmU6IEEgTGlmZSBvZiBKb2huIFNub3cqLiBPeGZvcmQ7IE5ldyBZb3JrOiBPeGZvcmQgVW5pdmVyc2l0eSBQcmVzcy4gTGlua2VkIG9uLWxpbmUgcmVzb3VyY2VzIGh0dHBzOi8vam9obnNub3cubWF0cml4Lm1zdS5lZHUvc25vd3dvcmtzLnBocAoKCgpUaGlzIGlzIGFuIFtSIE1hcmtkb3duXShodHRwOi8vcm1hcmtkb3duLnJzdHVkaW8uY29tKSBOb3RlYm9vay4gV2hlbiB5b3UgZXhlY3V0ZSBjb2RlIHdpdGhpbiB0aGUgbm90ZWJvb2ssIHRoZSByZXN1bHRzIGFwcGVhciBiZW5lYXRoIHRoZSBjb2RlLiBUaGUgcmVzdWx0cyBhcmUgYWxzbyBzYXZlZCBpbiBhIHNlbGYtY29udGFpbmVkIGh0bWwgZG9jdW1lbnQgd2l0aCB0aGUgc3VmZml4ICoubmIuaHRtbCouIElmIHlvdSB3YW50IHB1cmUgciBjb2RlIChmb3IgZXhhbXBsZSB0byBydW4gb3V0c2lkZSBSU3R1ZGlvKSB5b3UgY2FuIGVhc2lseSBleHRyYWN0IGNvZGUgd2l0aCB0aGUgY29tbWFuZCAqa25pdCgnbm90ZWJvb2suUm1kJyx0YW5nbGU9VFJVRSkqIHdoaWNoIHdpbGwgc2F2ZSBhIGZpbGUgJ25vdGVib29rLlInIHVuZGVyIHlvdXIgd29ya2luZyBkaXJlY3RvcnkuCgpUcnkgZXhlY3V0aW5nIHRoZSBjaHVuayBiZWxvdyBieSBjbGlja2luZyB0aGUgKlJ1biogYnV0dG9uIHdpdGhpbiB0aGUgY2h1bmsgb3IgYnkgcGxhY2luZyB5b3VyIGN1cnNvciBpbnNpZGUgaXQgYW5kIHByZXNzaW5nICpDbWQrU2hpZnQrRW50ZXIqLiAKCmBgYHtyfQojIENvcHlyaWdodCAoYykgMjAxOSwgVGhvbWFzIENvbGVtYW4KIwojICAtLS0tLS0tICBMaWNlbnNlZCB1bmRlciBCU0QgMi1DbGF1c2UgIlNpbXBsaWZpZWQiIExpY2Vuc2UgIC0tLS0tLS0KIwojIFJlc3VsdHMgYW5kIGRpc2N1c3Npb24gaW4gIkNhdXNhbGl0eSBpbiB0aGUgVGltZSBvZiBDaG9sZXJhOiBKb2huIFNub3cgYXMgYSBQcm90b3R5cGUgCiMgZm9yIENhdXNhbCBJbmZlcmVuY2UgKFdvcmtpbmcgUGFwZXIpIiBhdmFpbGFibGUgYXQgU1NSTjogaHR0cHM6Ly9wYXBlcnMuc3Nybi5jb20vYWJzdHJhY3Q9MzI2MjIzNAoKCnJtKGxpc3Q9bHMoKSkgICAgIyBzdGFydHMgYSBmcmVzaCB3b3Jrc3BhY2UKIwp0YWJsZXZpaSA8LSByZWFkLmNzdihmaWxlPSJTbm93MTg1NV9UYWJsZVZJSS5jc3YiLCBoZWFkZXI9VFJVRSwgc2VwPSIsIiwgc2tpcD01LGNvbW1lbnQuY2hhcj0iIyIpCnRhYmxldmlpaSA8LSByZWFkLmNzdihmaWxlPSJTbm93MTg1NV9UYWJsZVZJSUkuY3N2IiwgaGVhZGVyPVRSVUUsIHNlcD0iLCIsIHNraXA9NSxjb21tZW50LmNoYXI9IiMiKQp0YWJsZWl4IDwtIHJlYWQuY3N2KGZpbGU9IlNub3cxODU1X1RhYmxlSVguY3N2IiwgaGVhZGVyPVRSVUUsIHNlcD0iLCIsIHNraXA9NSxjb21tZW50LmNoYXI9IiMiKQp0YWJsZXhpaSA8LSByZWFkLmNzdihmaWxlPSJTbm93MTg1NV9UYWJsZVhJSS5jc3YiLCBoZWFkZXI9VFJVRSwgc2VwPSIsIiwgc2tpcD01LGNvbW1lbnQuY2hhcj0iIyIpCgpgYGAKCgpUaGVzZSB0YWJsZXMgYXJlICJkYXRhIGZyYW1lIiAoU2VlIGh0dHBzOi8vd3d3LnItYmxvZ2dlcnMuY29tLzE1LWVhc3ktc29sdXRpb25zLXRvLXlvdXItZGF0YS1mcmFtZS1wcm9ibGVtcy1pbi1yLyBmb3IgdHV0b3JpYWwgb24gZGF0YSBmcmFtZXMpLiBGb3IgZGF0YWZyYW1lcyBzdWJzZXR0aW5nIGlzIGVhc3kuIAoKCmBgYHtyfQpjbGFzcyh0YWJsZXhpaSkKCnN1YnNldCh0YWJsZXZpaWksc3VwcGxpZXI9PSJMYW1iZXRoIikKYGBgCgpDaGVjayBUYWJsZSBWSUkuIFNub3cncyBwdWJsaXNoZWQgdGFibGVzIHNob3cgdGhlIHRvdGFsIGluIHRoZSBsYXN0IHJvdyBmb3IgZWFjaCBjb2x1bW4sIHNvIHRoZSBzdW0gb2YgYWxsIHJvd3Mgc2hvdWxkIGJlIHR3aWNlIHRoZSBsYXN0IHJvdy4gVGhlIGZvbGxvd2luZyBjaGVja3MgdGhpcyBhbmQgYWxsIHJlc3VsdHMgc2hvdWxkIGJlIHplcm8uICAKYGBge3J9CmNvbFN1bXModGFibGV2aWlbLDI6OF0pIC0gMip0YWJsZXZpaVtucm93KHRhYmxldmlpKSwyOjhdCmBgYAoKQ2hlY2sgVGFibGUgVklJSS4gQWdhaW4sIHRoZSBzdW0gb2YgYWxsIHJvd3Mgc2hvdWxkIGJlIHR3aWNlIHRoZSBsYXN0IHJvdy4gVGhlIGZvbGxvd2luZyBzaG91bGQgYmUgemVyby4gIAoKYGBge3J9CmNvbFN1bXModGFibGV2aWlpWywyOjhdKSAtIDIqdGFibGV2aWlpW25yb3codGFibGV2aWlpKSwyOjhdCmBgYAoKV2UgY2FuIGNoZWNrIHRoZSBwb3B1bGF0aW9uIHN1Yi10b3RhbHMgaW4gVGFibGUgVklJSSAoZm9yICJmaXJzdCAxMiIsICJuZXh0IDE2IiBhbmQgbGFzdCAoTGFtYmV0aC1vbmx5KSBzdWItZGlzdHJpY3RzKSBhZ2FpbnN0IHRoZSBwb3B1bGF0aW9uIHN1Yi10b3RhbHMgc2hvd24gaW4gVGFibGUgVkkgKHAuIDczKS4gKE5vdGUgdGhhdCBUYWJsZSBWSSBzaG93cyBvbmx5IHRocmVlIG9mIHRoZSBmb3VyIExhbWJldGggc3ViLWRpc3RyaWN0cyAtIGV4Y2x1ZGVzIFN5ZGVuaGFtKS4gVGhlIHN1Yi10b3RhbHMgaW4gVGFibGUgVkkgYXJlOgoKKiBGaXJzdCAxMiAoU291dGh3YXJrICYgVmF1eGhhbGwpICAxNjcsNjU0CiogTmV4dCAxNiAoam9pbnQgU291dGh3YXJrICYgVmF1eGhhbGwgYW5kIExhbWJldGgpIDMwMSwxNDkKKiArIFRoaXMgc2VlbXMgdG8gYmUgYSB0eXBvIGluIFNub3cncyBUYWJsZSBWSSBhbmQgc2hvdWxkIHJlYWQgMzAwLDE0OSBzbyB0aGUgY29tcGFyaXNvbiB3aWxsIGJlIG9mZiBieSAxLDAwMAoqIExhc3QgMyAoTGFtYmV0aCBleGNsdWRpbmcgU3lkZW5oYW0pICAxNCw2MzIKKiArIFN5ZGVuaGFtIGlzIDQsNTAxIHNvIHRoZSBjb21wYXJpc29uIHdpbGwgYmUgb2ZmIGJ5IHRoaXMgYW1vdW50CgoKYGBge3J9CngxIDwtIGMoc3VtKHN1YnNldCh0YWJsZXZpaWksc3VwcGxpZXI9PSJTb3V0aHdhcmtWYXV4aGFsbCIpWywyXSksCiAgICAgICAgc3VtKHN1YnNldCh0YWJsZXZpaWksc3VwcGxpZXI9PSJTb3V0aHdhcmtWYXV4aGFsbF9MYW1iZXRoIilbLDJdKSwKICAgICAgICBzdW0oc3Vic2V0KHRhYmxldmlpaSxzdXBwbGllcj09IkxhbWJldGgiKVssMl0pKQp4MSAtIGMoMTY3NjU0LCAzMDExNDksIDE0NjMyKQpgYGAKClRhYmxlIFhJSSBoYXMgZGVhdGhzIGZvciAxODQ5IGFuZCAxODU0IGJ5IHN1Yi1kaXN0cmljdC4gV2UgY2FuIGNoZWNrIGFzIGZvbGxvd3M6IAoKKiBTdWJzZXQgYnkgIlNvdXRod2Fya1ZhdXhoYWxsIiwgIlNvdXRod2Fya1ZhdXhoYWxsX0xhbWJldGgiLCAiTGFtYmV0aCIgdG8gZ2V0IHRoZSAiZmlyc3QgMTIiLCAibmV4dCAxNiIsIGFuZCAiZmluYWwgNCIgc3ViLWRpc3RyaWN0cwoqIFN1bSBvdmVyIHRoZXNlIHN1YnNldHMKKiBTbm93IHJlcG9ydHMgdGhlc2Ugc3ViLXRvdGFscyBpbiB0aGUgbGFzdCB0aHJlZSByb3dzIG9mIFRhYmxlIFhJSQoqIFRoZSBmb2xsb3dpbmcgY2hlY2sgd2lsbCBzaG93IHplcm9zIHdoZW4gdGhlIHN1bXMgb3ZlciB0aGUgc3ViLXNldHRlZCBkYXRhIGVxdWFsIHRoZSByZXBvcnRlZCBzdWItdG90YWxzCgoKYGBge3J9Cnhjb21wIDwtIG1hdHJpeChkYXRhPTAsbnJvdz0zLG5jb2w9MikKY29sbmFtZXMoeGNvbXApIDwtIGMoImRlYXRoczE4NDkiLCJkZWF0aHMxODU0IikKcm93bmFtZXMoeGNvbXApIDwtIGMoImZpcnN0MTIiLCJuZXh0MTYiLCJsYXN0NCIpCnhjb21wIDwtIGFzLmRhdGEuZnJhbWUoeGNvbXApCngxIDwtIHN1YnNldCh0YWJsZXhpaSxzdXBwbGllcj09IlNvdXRod2Fya1ZhdXhoYWxsIikKeDIgPC0gY29sU3Vtcyh4MVssMjozXSkKeDMgPC0gc3Vic2V0KHRhYmxleGlpLHN1cHBsaWVyPT0iZmlyc3QxMiIpCnhjb21wWzEsXSA8LSB4Mi14M1syOjNdCngxIDwtIHN1YnNldCh0YWJsZXhpaSxzdXBwbGllcj09IlNvdXRod2Fya1ZhdXhoYWxsX0xhbWJldGgiKQp4MiA8LSBjb2xTdW1zKHgxWywyOjNdKQp4MyA8LSBzdWJzZXQodGFibGV4aWksc3VwcGxpZXI9PSJuZXh0MTYiKQojcHJpbnQoIkRlYXRoIHN1Yi10b3RhbCBmb3IgU291dGh3YXJrVmF1eGhhbGwgJiBMYW1iZXRoIGNoZWNrZWQgYWdhaW5zdCBTbm93J3Mgc3VidG90YWwgKHNob3VsZCBiZSB6ZXJvKSIpCnhjb21wWzIsXSA8LSB4Mi14M1syOjNdCngxIDwtIHN1YnNldCh0YWJsZXhpaSxzdXBwbGllcj09IkxhbWJldGgiKQp4MiA8LSBjb2xTdW1zKHgxWywyOjNdKQp4MyA8LSBzdWJzZXQodGFibGV4aWksc3VwcGxpZXI9PSJsYXN0NCIpCiNwcmludCgiRGVhdGggc3ViLXRvdGFsIGZvciBMYW1iZXRoIGNoZWNrZWQgYWdhaW5zdCBTbm93J3Mgc3VidG90YWwgKHNob3VsZCBiZSB6ZXJvKSIpCnhjb21wWzMsXSA8LSB4Mi14M1syOjNdCnhjb21wCmBgYAoKCmBgYHtyfQp0YWJsZXZpaQp0YWJsZXZpaWkKdGFibGVpeAp0YWJsZXhpaQpgYGAKCg==