The heredity of height. Published in 1903 by Karl Pearson and Alice Lee. See Chapter 6 in Regression and Other Stories.


Load packages

library("rprojroot")
root<-has_file(".ROS-Examples-root")$make_fix_file()
library("rstanarm")
library("HistData")

Load data

heights <- read.table(root("PearsonLee/data","Heights.txt"), header=TRUE)
n <- nrow(heights)
head(heights)
  daughter_height mother_height
1            52.5          59.5
2            52.5          59.5
3            53.5          59.5
4            53.5          59.5
5            55.5          59.5
6            55.5          59.5

Linear regression

fit_1 <- stan_glm(daughter_height ~ mother_height, data = heights, refresh = 0)
print(fit_1, digits=2)
stan_glm
 family:       gaussian [identity]
 formula:      daughter_height ~ mother_height
 observations: 5524
 predictors:   2
------
              Median MAD_SD
(Intercept)   29.81   0.79 
mother_height  0.54   0.01 

Auxiliary parameter(s):
      Median MAD_SD
sigma 2.26   0.02  

------
* For help interpreting the printed output see ?print.stanreg
* For info on the priors used see ?prior_summary.stanreg
a_hat <- coef(fit_1)[1]
b_hat <- coef(fit_1)[2]

Plot mothers' and daughters' heights

par(mar=c(3, 3, 2, 1), mgp=c(1.7, .5, 0), tck=-.01)
par(pty="s")
rng <- range(heights$mother_height, heights$daughter_height)
plot(heights$mother_height, heights$daughter_height, xlab="Mother's height (inches)", ylab="Adult daughter's height (inches)", bty="l", xlim=rng, ylim=rng, xaxt="n", yaxt="n", pch=20, cex=.5)
x <- seq(48, 84, 6)
axis(1, x)
axis(2, x)
for (i in x){
  abline(h=i, col="gray70", lty=2)
  abline(v=i, col="gray70", lty=2)
}

Plot mothers' and daughters' heights with jitter

par(mar=c(3, 3, 2, 1), mgp=c(1.7, .5, 0), tck=-.01, pty="s")
plot(jitter(heights$mother_height, 0.5), jitter(heights$daughter_height), xlab="Mother's height (inches)", ylab="Adult daughter's height (inches)", bty="l", xlim=rng, ylim=rng, xaxt="n", yaxt="n", pch=20, cex=.2)
x <- seq(48, 84, 6)
axis(1, x)
axis(2, x)
for (i in x){
  abline(h=i, col="gray70", lty=2)
  abline(v=i, col="gray70", lty=2)
}

Plot mothers' and daughters' heights and fitted regression line

par(mar=c(3, 3, 2, .1), mgp=c(2, .5, 0), tck=-.01, pty="s")
plot(jitter(heights$mother_height, 0.5), jitter(heights$daughter_height), xlab="Mother's height (inches)", ylab="Adult daughter's height (inches)", bty="l", xlim=c(rng[1], rng[2]), ylim=rng, xaxt="n", yaxt="n", pch=20, cex=.2)
x <- seq(48, 84, 6)
axis(1, x)
axis(2, x)
for (i in x){
  abline(h=i, col="gray70", lty=2)
  abline(v=i, col="gray70", lty=2)
}
abline(a_hat, b_hat, lwd=3, col="white")
abline(a_hat, b_hat, lwd=1.5)
points(mean(heights$mother_height), mean(heights$daughter_height), pch=20, cex=2, col="white")
mtext("Mothers' and daughters' heights,\naverage of data, and fitted regression line", side=3, line=0)

Plot fitted regression line and the average of the data

par(mar=c(3, 3, 2, .1), mgp=c(2, .5, 0), tck=-.01, pty="s")
plot(jitter(heights$mother_height, 0.5), jitter(heights$daughter_height), xlab="Mother's height (inches)", ylab="Adult daughter's height (inches)", bty="l", xlim=c(rng[1], rng[2]), ylim=rng, xaxt="n", yaxt="n", pch=20, cex=.2, type="n")
x <- seq(54, 72, 6)
axis(1, x)
axis(2, x)
abline(a_hat, b_hat, lwd=3, col="white")
abline(a_hat, b_hat, lwd=1.5)
lines(rep(mean(heights$mother_height), 2), c(0, mean(heights$daughter_height)), lwd=.5)
lines(c(0, mean(heights$mother_height)), rep(mean(heights$daughter_height), 2), lwd=.5)
axis(1, mean(heights$mother_height), round(mean(heights$mother_height), 1))
axis(2, mean(heights$daughter_height), round(mean(heights$daughter_height), 1))
text(68, 64, paste("y =", round(a_hat), "+", round(b_hat, 2), "x"))
text(63, 62, paste("Equivalently,  y = ", round(mean(heights$daughter_height), 1), " + ", round(b_hat, 2), " * (x - ", round(mean(heights$mother_height), 1), ")", sep=""))
points(mean(heights$mother_height), mean(heights$daughter_height), pch=20, cex=2)
mtext("The fitted regression line and the average of the data      ", side=3, line=1)

Plot fitted regression line

par(mar=c(3, 3, 2, .1), mgp=c(2, .5, 0), tck=-.01)
plot(c(0, 100), c(0, 100), xlab="", ylab="", xaxt="n", yaxt="n", bty="n", type="n")
abline(h=0)
abline(v=0)
axis(2, round(a_hat), tck=0, las=1)
axis(1, 0, tck=0, las=1, line=-.4)
axis(2, 0, tck=0, las=1)
abline(a_hat, b_hat, lwd=2)
text(40, 40, paste("slope", round(b_hat, 2)))
mtext(paste("The line, y =", round(a_hat), "+", round(b_hat, 2), "x"), side=3, line=0)

Plot data and fitted regression line in the context of the data

par(mar=c(3, 3, 2, .1), mgp=c(2, .5, 0), tck=-.01)
plot(c(0, 100), c(0, 100), xlab="", ylab="", xaxt="n", yaxt="n", bty="n", type="n")
abline(h=0)
abline(v=0)
axis(2, round(a_hat), tck=0, las=1)
points(jitter(heights$mother_height, 0.5), jitter(heights$daughter_height), pch=20, cex=.2)
abline(a_hat, b_hat, lwd=3, col="white")
abline(a_hat, b_hat, lwd=1.5)
axis(1, 0, tck=0, las=1, line=-.4)
axis(2, 0, tck=0, las=1)
axis(1, mean(heights$mother_height), round(mean(heights$mother_height), 1), tck=0, las=1, line=-.4)
axis(2, mean(heights$daughter_height), round(mean(heights$daughter_height), 1), tck=0, las=1, line=-.7)
lines(rep(mean(heights$mother_height), 2), c(0, mean(heights$daughter_height)), lwd=.5)
lines(c(0, mean(heights$mother_height)), rep(mean(heights$daughter_height), 2), lwd=.5)
text(40, 43, paste("slope", round(b_hat, 2)), cex=.9)
mtext(paste("The line, y =", round(a_hat), "+", round(b_hat, 2), "x, in the context of the data"), side=3, line=0)

LS0tCnRpdGxlOiAiUmVncmVzc2lvbiBhbmQgT3RoZXIgU3RvcmllczogUGVhcnNvbiBhbmQgTGVlIEhlaWdodHMiCmF1dGhvcjogIkFuZHJldyBHZWxtYW4sIEplbm5pZmVyIEhpbGwsIEFraSBWZWh0YXJpIgpkYXRlOiAiYHIgZm9ybWF0KFN5cy5EYXRlKCkpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0aGVtZTogcmVhZGFibGUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2RlcHRoOiAyCiAgICB0b2NfZmxvYXQ6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKLS0tCgpUaGUgaGVyZWRpdHkgb2YgaGVpZ2h0LiBQdWJsaXNoZWQgaW4gMTkwMyBieSBLYXJsIFBlYXJzb24gYW5kIEFsaWNlCkxlZS4gU2VlIENoYXB0ZXIgNiBpbiBSZWdyZXNzaW9uIGFuZCBPdGhlciBTdG9yaWVzLgoKLS0tLS0tLS0tLS0tLQoKCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQobWVzc2FnZT1GQUxTRSwgZXJyb3I9RkFMU0UsIHdhcm5pbmc9RkFMU0UsIGNvbW1lbnQ9TkEpCiMgc3dpdGNoIHRoaXMgdG8gVFJVRSB0byBzYXZlIGZpZ3VyZXMgaW4gc2VwYXJhdGUgZmlsZXMKc2F2ZWZpZ3MgPC0gRkFMU0UKYGBgCgojIyMjIExvYWQgcGFja2FnZXMKCmBgYHtyIH0KbGlicmFyeSgicnByb2pyb290IikKcm9vdDwtaGFzX2ZpbGUoIi5ST1MtRXhhbXBsZXMtcm9vdCIpJG1ha2VfZml4X2ZpbGUoKQpsaWJyYXJ5KCJyc3RhbmFybSIpCmxpYnJhcnkoIkhpc3REYXRhIikKYGBgCgojIyMjIExvYWQgZGF0YQoKYGBge3IgfQpoZWlnaHRzIDwtIHJlYWQudGFibGUocm9vdCgiUGVhcnNvbkxlZS9kYXRhIiwiSGVpZ2h0cy50eHQiKSwgaGVhZGVyPVRSVUUpCm4gPC0gbnJvdyhoZWlnaHRzKQpoZWFkKGhlaWdodHMpCmBgYAoKIyMjIyBMaW5lYXIgcmVncmVzc2lvbgoKYGBge3IgfQpmaXRfMSA8LSBzdGFuX2dsbShkYXVnaHRlcl9oZWlnaHQgfiBtb3RoZXJfaGVpZ2h0LCBkYXRhID0gaGVpZ2h0cywgcmVmcmVzaCA9IDApCmBgYApgYGB7ciB9CnByaW50KGZpdF8xLCBkaWdpdHM9MikKYV9oYXQgPC0gY29lZihmaXRfMSlbMV0KYl9oYXQgPC0gY29lZihmaXRfMSlbMl0KYGBgCgojIyMjIFBsb3QgbW90aGVycycgYW5kIGRhdWdodGVycycgaGVpZ2h0cwoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KaWYgKHNhdmVmaWdzKSBwZGYocm9vdCgiUGVhcnNvbkxlZS9maWdzIiwiUGVhcnNvbkxlZTEucGRmIiksIGhlaWdodD00LjUsIHdpZHRoPTQuNSkKYGBgCmBgYHtyIH0KcGFyKG1hcj1jKDMsIDMsIDIsIDEpLCBtZ3A9YygxLjcsIC41LCAwKSwgdGNrPS0uMDEpCnBhcihwdHk9InMiKQpybmcgPC0gcmFuZ2UoaGVpZ2h0cyRtb3RoZXJfaGVpZ2h0LCBoZWlnaHRzJGRhdWdodGVyX2hlaWdodCkKcGxvdChoZWlnaHRzJG1vdGhlcl9oZWlnaHQsIGhlaWdodHMkZGF1Z2h0ZXJfaGVpZ2h0LCB4bGFiPSJNb3RoZXIncyBoZWlnaHQgKGluY2hlcykiLCB5bGFiPSJBZHVsdCBkYXVnaHRlcidzIGhlaWdodCAoaW5jaGVzKSIsIGJ0eT0ibCIsIHhsaW09cm5nLCB5bGltPXJuZywgeGF4dD0ibiIsIHlheHQ9Im4iLCBwY2g9MjAsIGNleD0uNSkKeCA8LSBzZXEoNDgsIDg0LCA2KQpheGlzKDEsIHgpCmF4aXMoMiwgeCkKZm9yIChpIGluIHgpewogIGFibGluZShoPWksIGNvbD0iZ3JheTcwIiwgbHR5PTIpCiAgYWJsaW5lKHY9aSwgY29sPSJncmF5NzAiLCBsdHk9MikKfQpgYGAKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KaWYgKHNhdmVmaWdzKSBkZXYub2ZmKCkKYGBgCgojIyMjIFBsb3QgbW90aGVycycgYW5kIGRhdWdodGVycycgaGVpZ2h0cyB3aXRoIGppdHRlcgoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KaWYgKHNhdmVmaWdzKSBwZGYocm9vdCgiUGVhcnNvbkxlZS9maWdzIiwiUGVhcnNvbkxlZTIucGRmIiksIGhlaWdodD00LjUsIHdpZHRoPTQuNSkKYGBgCmBgYHtyIH0KcGFyKG1hcj1jKDMsIDMsIDIsIDEpLCBtZ3A9YygxLjcsIC41LCAwKSwgdGNrPS0uMDEsIHB0eT0icyIpCnBsb3Qoaml0dGVyKGhlaWdodHMkbW90aGVyX2hlaWdodCwgMC41KSwgaml0dGVyKGhlaWdodHMkZGF1Z2h0ZXJfaGVpZ2h0KSwgeGxhYj0iTW90aGVyJ3MgaGVpZ2h0IChpbmNoZXMpIiwgeWxhYj0iQWR1bHQgZGF1Z2h0ZXIncyBoZWlnaHQgKGluY2hlcykiLCBidHk9ImwiLCB4bGltPXJuZywgeWxpbT1ybmcsIHhheHQ9Im4iLCB5YXh0PSJuIiwgcGNoPTIwLCBjZXg9LjIpCnggPC0gc2VxKDQ4LCA4NCwgNikKYXhpcygxLCB4KQpheGlzKDIsIHgpCmZvciAoaSBpbiB4KXsKICBhYmxpbmUoaD1pLCBjb2w9ImdyYXk3MCIsIGx0eT0yKQogIGFibGluZSh2PWksIGNvbD0iZ3JheTcwIiwgbHR5PTIpCn0KYGBgCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmlmIChzYXZlZmlncykgZGV2Lm9mZigpCmBgYAoKIyMjIyBQbG90IG1vdGhlcnMnIGFuZCBkYXVnaHRlcnMnIGhlaWdodHMgYW5kIGZpdHRlZCByZWdyZXNzaW9uIGxpbmUKCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmlmIChzYXZlZmlncykgcGRmKHJvb3QoIlBlYXJzb25MZWUvZmlncyIsIlBlYXJzb25MZWUzYS5wZGYiKSwgaGVpZ2h0PTQuNSwgd2lkdGg9NC41KQpgYGAKYGBge3IgfQpwYXIobWFyPWMoMywgMywgMiwgLjEpLCBtZ3A9YygyLCAuNSwgMCksIHRjaz0tLjAxLCBwdHk9InMiKQpwbG90KGppdHRlcihoZWlnaHRzJG1vdGhlcl9oZWlnaHQsIDAuNSksIGppdHRlcihoZWlnaHRzJGRhdWdodGVyX2hlaWdodCksIHhsYWI9Ik1vdGhlcidzIGhlaWdodCAoaW5jaGVzKSIsIHlsYWI9IkFkdWx0IGRhdWdodGVyJ3MgaGVpZ2h0IChpbmNoZXMpIiwgYnR5PSJsIiwgeGxpbT1jKHJuZ1sxXSwgcm5nWzJdKSwgeWxpbT1ybmcsIHhheHQ9Im4iLCB5YXh0PSJuIiwgcGNoPTIwLCBjZXg9LjIpCnggPC0gc2VxKDQ4LCA4NCwgNikKYXhpcygxLCB4KQpheGlzKDIsIHgpCmZvciAoaSBpbiB4KXsKICBhYmxpbmUoaD1pLCBjb2w9ImdyYXk3MCIsIGx0eT0yKQogIGFibGluZSh2PWksIGNvbD0iZ3JheTcwIiwgbHR5PTIpCn0KYWJsaW5lKGFfaGF0LCBiX2hhdCwgbHdkPTMsIGNvbD0id2hpdGUiKQphYmxpbmUoYV9oYXQsIGJfaGF0LCBsd2Q9MS41KQpwb2ludHMobWVhbihoZWlnaHRzJG1vdGhlcl9oZWlnaHQpLCBtZWFuKGhlaWdodHMkZGF1Z2h0ZXJfaGVpZ2h0KSwgcGNoPTIwLCBjZXg9MiwgY29sPSJ3aGl0ZSIpCm10ZXh0KCJNb3RoZXJzJyBhbmQgZGF1Z2h0ZXJzJyBoZWlnaHRzLFxuYXZlcmFnZSBvZiBkYXRhLCBhbmQgZml0dGVkIHJlZ3Jlc3Npb24gbGluZSIsIHNpZGU9MywgbGluZT0wKQpgYGAKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KaWYgKHNhdmVmaWdzKSBkZXYub2ZmKCkKYGBgCgojIyMjIFBsb3QgZml0dGVkIHJlZ3Jlc3Npb24gbGluZSBhbmQgdGhlIGF2ZXJhZ2Ugb2YgdGhlIGRhdGEKCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmlmIChzYXZlZmlncykgcGRmKHJvb3QoIlBlYXJzb25MZWUvZmlncyIsIlBlYXJzb25MZWUzYi5wZGYiKSwgaGVpZ2h0PTQuNSwgd2lkdGg9NC41KQpgYGAKYGBge3IgfQpwYXIobWFyPWMoMywgMywgMiwgLjEpLCBtZ3A9YygyLCAuNSwgMCksIHRjaz0tLjAxLCBwdHk9InMiKQpwbG90KGppdHRlcihoZWlnaHRzJG1vdGhlcl9oZWlnaHQsIDAuNSksIGppdHRlcihoZWlnaHRzJGRhdWdodGVyX2hlaWdodCksIHhsYWI9Ik1vdGhlcidzIGhlaWdodCAoaW5jaGVzKSIsIHlsYWI9IkFkdWx0IGRhdWdodGVyJ3MgaGVpZ2h0IChpbmNoZXMpIiwgYnR5PSJsIiwgeGxpbT1jKHJuZ1sxXSwgcm5nWzJdKSwgeWxpbT1ybmcsIHhheHQ9Im4iLCB5YXh0PSJuIiwgcGNoPTIwLCBjZXg9LjIsIHR5cGU9Im4iKQp4IDwtIHNlcSg1NCwgNzIsIDYpCmF4aXMoMSwgeCkKYXhpcygyLCB4KQphYmxpbmUoYV9oYXQsIGJfaGF0LCBsd2Q9MywgY29sPSJ3aGl0ZSIpCmFibGluZShhX2hhdCwgYl9oYXQsIGx3ZD0xLjUpCmxpbmVzKHJlcChtZWFuKGhlaWdodHMkbW90aGVyX2hlaWdodCksIDIpLCBjKDAsIG1lYW4oaGVpZ2h0cyRkYXVnaHRlcl9oZWlnaHQpKSwgbHdkPS41KQpsaW5lcyhjKDAsIG1lYW4oaGVpZ2h0cyRtb3RoZXJfaGVpZ2h0KSksIHJlcChtZWFuKGhlaWdodHMkZGF1Z2h0ZXJfaGVpZ2h0KSwgMiksIGx3ZD0uNSkKYXhpcygxLCBtZWFuKGhlaWdodHMkbW90aGVyX2hlaWdodCksIHJvdW5kKG1lYW4oaGVpZ2h0cyRtb3RoZXJfaGVpZ2h0KSwgMSkpCmF4aXMoMiwgbWVhbihoZWlnaHRzJGRhdWdodGVyX2hlaWdodCksIHJvdW5kKG1lYW4oaGVpZ2h0cyRkYXVnaHRlcl9oZWlnaHQpLCAxKSkKdGV4dCg2OCwgNjQsIHBhc3RlKCJ5ID0iLCByb3VuZChhX2hhdCksICIrIiwgcm91bmQoYl9oYXQsIDIpLCAieCIpKQp0ZXh0KDYzLCA2MiwgcGFzdGUoIkVxdWl2YWxlbnRseSwgIHkgPSAiLCByb3VuZChtZWFuKGhlaWdodHMkZGF1Z2h0ZXJfaGVpZ2h0KSwgMSksICIgKyAiLCByb3VuZChiX2hhdCwgMiksICIgKiAoeCAtICIsIHJvdW5kKG1lYW4oaGVpZ2h0cyRtb3RoZXJfaGVpZ2h0KSwgMSksICIpIiwgc2VwPSIiKSkKcG9pbnRzKG1lYW4oaGVpZ2h0cyRtb3RoZXJfaGVpZ2h0KSwgbWVhbihoZWlnaHRzJGRhdWdodGVyX2hlaWdodCksIHBjaD0yMCwgY2V4PTIpCm10ZXh0KCJUaGUgZml0dGVkIHJlZ3Jlc3Npb24gbGluZSBhbmQgdGhlIGF2ZXJhZ2Ugb2YgdGhlIGRhdGEgICAgICAiLCBzaWRlPTMsIGxpbmU9MSkKYGBgCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmlmIChzYXZlZmlncykgZGV2Lm9mZigpCmBgYAoKIyMjIyBQbG90IGZpdHRlZCByZWdyZXNzaW9uIGxpbmUKCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmlmIChzYXZlZmlncykgcGRmKHJvb3QoIlBlYXJzb25MZWUvZmlncyIsIlBlYXJzb25MZWU0YS5wZGYiKSwgaGVpZ2h0PTQsIHdpZHRoPTQuNSkKYGBgCmBgYHtyIH0KcGFyKG1hcj1jKDMsIDMsIDIsIC4xKSwgbWdwPWMoMiwgLjUsIDApLCB0Y2s9LS4wMSkKcGxvdChjKDAsIDEwMCksIGMoMCwgMTAwKSwgeGxhYj0iIiwgeWxhYj0iIiwgeGF4dD0ibiIsIHlheHQ9Im4iLCBidHk9Im4iLCB0eXBlPSJuIikKYWJsaW5lKGg9MCkKYWJsaW5lKHY9MCkKYXhpcygyLCByb3VuZChhX2hhdCksIHRjaz0wLCBsYXM9MSkKYXhpcygxLCAwLCB0Y2s9MCwgbGFzPTEsIGxpbmU9LS40KQpheGlzKDIsIDAsIHRjaz0wLCBsYXM9MSkKYWJsaW5lKGFfaGF0LCBiX2hhdCwgbHdkPTIpCnRleHQoNDAsIDQwLCBwYXN0ZSgic2xvcGUiLCByb3VuZChiX2hhdCwgMikpKQptdGV4dChwYXN0ZSgiVGhlIGxpbmUsIHkgPSIsIHJvdW5kKGFfaGF0KSwgIisiLCByb3VuZChiX2hhdCwgMiksICJ4IiksIHNpZGU9MywgbGluZT0wKQpgYGAKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KaWYgKHNhdmVmaWdzKSBkZXYub2ZmKCkKYGBgCgojIyMjIFBsb3QgZGF0YSBhbmQgZml0dGVkIHJlZ3Jlc3Npb24gbGluZSBpbiB0aGUgY29udGV4dCBvZiB0aGUgZGF0YQoKYGBge3IgZXZhbD1GQUxTRSwgaW5jbHVkZT1GQUxTRX0KaWYgKHNhdmVmaWdzKSBwZGYocm9vdCgiUGVhcnNvbkxlZS9maWdzIiwiUGVhcnNvbkxlZTRiLnBkZiIpLCBoZWlnaHQ9NCwgd2lkdGg9NC41KQpgYGAKYGBge3IgfQpwYXIobWFyPWMoMywgMywgMiwgLjEpLCBtZ3A9YygyLCAuNSwgMCksIHRjaz0tLjAxKQpwbG90KGMoMCwgMTAwKSwgYygwLCAxMDApLCB4bGFiPSIiLCB5bGFiPSIiLCB4YXh0PSJuIiwgeWF4dD0ibiIsIGJ0eT0ibiIsIHR5cGU9Im4iKQphYmxpbmUoaD0wKQphYmxpbmUodj0wKQpheGlzKDIsIHJvdW5kKGFfaGF0KSwgdGNrPTAsIGxhcz0xKQpwb2ludHMoaml0dGVyKGhlaWdodHMkbW90aGVyX2hlaWdodCwgMC41KSwgaml0dGVyKGhlaWdodHMkZGF1Z2h0ZXJfaGVpZ2h0KSwgcGNoPTIwLCBjZXg9LjIpCmFibGluZShhX2hhdCwgYl9oYXQsIGx3ZD0zLCBjb2w9IndoaXRlIikKYWJsaW5lKGFfaGF0LCBiX2hhdCwgbHdkPTEuNSkKYXhpcygxLCAwLCB0Y2s9MCwgbGFzPTEsIGxpbmU9LS40KQpheGlzKDIsIDAsIHRjaz0wLCBsYXM9MSkKYXhpcygxLCBtZWFuKGhlaWdodHMkbW90aGVyX2hlaWdodCksIHJvdW5kKG1lYW4oaGVpZ2h0cyRtb3RoZXJfaGVpZ2h0KSwgMSksIHRjaz0wLCBsYXM9MSwgbGluZT0tLjQpCmF4aXMoMiwgbWVhbihoZWlnaHRzJGRhdWdodGVyX2hlaWdodCksIHJvdW5kKG1lYW4oaGVpZ2h0cyRkYXVnaHRlcl9oZWlnaHQpLCAxKSwgdGNrPTAsIGxhcz0xLCBsaW5lPS0uNykKbGluZXMocmVwKG1lYW4oaGVpZ2h0cyRtb3RoZXJfaGVpZ2h0KSwgMiksIGMoMCwgbWVhbihoZWlnaHRzJGRhdWdodGVyX2hlaWdodCkpLCBsd2Q9LjUpCmxpbmVzKGMoMCwgbWVhbihoZWlnaHRzJG1vdGhlcl9oZWlnaHQpKSwgcmVwKG1lYW4oaGVpZ2h0cyRkYXVnaHRlcl9oZWlnaHQpLCAyKSwgbHdkPS41KQp0ZXh0KDQwLCA0MywgcGFzdGUoInNsb3BlIiwgcm91bmQoYl9oYXQsIDIpKSwgY2V4PS45KQptdGV4dChwYXN0ZSgiVGhlIGxpbmUsIHkgPSIsIHJvdW5kKGFfaGF0KSwgIisiLCByb3VuZChiX2hhdCwgMiksICJ4LCBpbiB0aGUgY29udGV4dCBvZiB0aGUgZGF0YSIpLCBzaWRlPTMsIGxpbmU9MCkKYGBgCmBgYHtyIGV2YWw9RkFMU0UsIGluY2x1ZGU9RkFMU0V9CmlmIChzYXZlZmlncykgZGV2Lm9mZigpCmBgYAoK