1 . Question 1 pgm-1 locus

1.1 . Create data frame of observed values

dat <- data.frame(AA = c(634), Aa = c(391), aa = c(85), row.names = c("observed genotype counts"))
Warning messages:
1: In scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  :
  EOF within quoted string
2: In scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  :
  EOF within quoted string
3: In scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  :
  EOF within quoted string
4: In scan(file = file, what = what, sep = sep, quote = quote, dec = dec,  :
  EOF within quoted string
dat

1.2 . Calculate allele frequencies to work out expected genotype

proportions (e.g. 1 = p^2+q^2+2pq)
allele_freq <- cbind(((2*dat$AA) + dat$Aa)/(2*rowSums(dat)),
  ((2*dat$aa) + dat$Aa)/(2*rowSums(dat)))
  colnames(allele_freq) <- c("A", "a")
allele_freq
                                 A         a
observed genotype counts 0.7472973 0.2527027

1.3 . Calculate expected genotype proportions under Hardy-Weinberg Equillibrium

HWEexpected <- t(apply(allele_freq, 1, function(x){
  AA <- x["A"]^2
  Aa <- 2*x["A"]*x["a"]
  aa <- x["a"]^2
  return(cbind(AA, Aa, aa))
  }))
HWEexpected
                              [,1]      [,2]       [,3]
observed genotype counts 0.5584533 0.3776881 0.06385866

1.4 . Chisquare test for observed vs expected HWE values

# convert genotypes and proportions into lists for efficient tests
dat <- lapply(1:nrow(dat), function(i) return(as.vector(dat[i,])))
HWEexpected <- lapply(1:nrow(HWEexpected), function(i){
return(as.vector(HWEexpected[i,]))
})
# Run HWE test
mapply(FUN = chisq.test, x = dat, p = HWEexpected, SIMPLIFY = FALSE)
[[1]]

    Chi-squared test for given probabilities

data:  dots[[1L]][[1L]]
X-squared = 5.0344, df = 2, p-value = 0.08068

The p-value is greater than 0.05 so we fail to reject the null hypothesis that the population is in Hardy-Weinberg Equilibrium

2 . Question 2 Serum Haptotypes in Egyptians

2.1 . Create data frame of observed values

dat2 <- data.frame(pp = c(9), pq = c(135), pr = c(2), qq = c(75),  qr = c(39), rr = c(25), row.names =
                    c("observed genotype counts"))
dat2

2.2 . Calculate allele frequencies to work out expected genotype

proportions (e.g. 1 = p^2+q^2+2pq)
allele_freq <- cbind(((2*dat2$pp) + dat2$pq + dat2$pr)/(2*rowSums(dat2)),
   ((2*dat2$qq) + dat2$pq + dat2$qr)/(2*rowSums(dat2)),
  ((2*dat2$rr) + dat2$pr + dat2$qr)/(2*rowSums(dat2)))
colnames(allele_freq) <- c("p", "q", "r")
row.names(allele_freq) <- c("gene frequency")
allele_freq
                       p         q         r
gene frequency 0.2719298 0.5684211 0.1596491

2.3 . Calculate expected genotype proportions under Hardy-Weinberg Equillibrium

HWEexpected <- t(apply(allele_freq, 1, function(x){
  pp <- x["p"]^2
  pq <- 2*x["p"]*x["q"]
  pr <- 2*x["p"]*x["r"]
  qq <- x["q"]^2
  qr <- 2*x["q"]*x["r"]
  rr <- x["r"]^2
  return(cbind(pp, pq, pr, qq, qr, rr))
  }))
colnames(HWEexpected) <- c("pp", "pq", "pr", "qq", "qr", "rr")
HWEexpected
                       pp        pq         pr        qq        qr         rr
gene frequency 0.07394583 0.3091413 0.08682672 0.3231025 0.1814958 0.02548784

2.4 . Chisquare test for observed vs expected HWE values

# convert genotypes and proportions into lists for efficient tests
dat2 <- lapply(1:nrow(dat2), function(i) return(as.vector(dat2[i,])))
HWEexpected <- lapply(1:nrow(HWEexpected), function(i){
return(as.vector(HWEexpected[i,]))
})
# Run HWE test
mapply(FUN = chisq.test, x = dat2, p = HWEexpected, SIMPLIFY = FALSE)
[[1]]

    Chi-squared test for given probabilities

data:  dots[[1L]][[1L]]
X-squared = 102.39, df = 5, p-value < 2.2e-16

p-value is less than 0.05 so we reject the null of HWE.

3 . Question 3 M-N blood groups

3.1 . Create data frame of observed values

dat3 <- data.frame(M = c(475, 195, 896, 14), MN = c(89, 215, 1559, 48), N = c(5, 79, 645, 138), row.names = c("Eskimos", "Russians", "Belgians", "Papuans"))
dat3

3.2 . Calculate allele frequencies to work out expected genotype

proportions (e.g. 1 = p^2+q^2+2pq)

3.2.1 . Eskimos

allele_freq_esk <- cbind(((2*dat3[1,1]) + dat3[1,2])/(2*sum(dat3[1,])),
  ((2*dat3[1,3]) + dat3[1,2])/(2*sum(dat3[1,])))
  colnames(allele_freq_esk) <- c("M", "N")
allele_freq_esk
             M          N
[1,] 0.9130053 0.08699473

3.2.2 . Russians

allele_freq_rus <- cbind(((2*dat3[2,1]) + dat3[2,2])/(2*sum(dat3[2,])),
  ((2*dat3[2,3]) + dat3[2,2])/(2*sum(dat3[2,])))
  colnames(allele_freq_rus) <- c("M", "N")
allele_freq_rus
             M         N
[1,] 0.6186094 0.3813906

3.2.3 . Belgians

allele_freq_bel <- cbind(((2*dat3[3,1]) + dat3[3,2])/(2*sum(dat3[3,])),
  ((2*dat3[3,3]) + dat3[3,2])/(2*sum(dat3[3,])))
  colnames(allele_freq_bel) <- c("M", "N")
allele_freq_bel
             M         N
[1,] 0.5404839 0.4595161

3.2.4 . Papuans

allele_freq_pap <- cbind(((2*dat3[4,1]) + dat3[4,2])/(2*sum(dat3[4,])),
  ((2*dat3[4,3]) + dat3[4,2])/(2*sum(dat3[4,])))
  colnames(allele_freq_pap) <- c("M", "N")
allele_freq_pap
        M    N
[1,] 0.19 0.81

3.3 . Calculate expected genotype proportions under Hardy-Weinberg Equillibrium

3.3.1 . Eskimos

HWEexpected_esk <- t(apply(allele_freq_esk, 1, function(x){
  M <- x["M"]^2
  MN <- 2*x["M"]*x["N"]
  N <- x["N"]^2
  return(cbind(M,MN,N))
  }))
colnames(HWEexpected_esk) <- c("M", "MN", "N")
HWEexpected_esk
             M        MN           N
[1,] 0.8335786 0.1588533 0.007568083

3.3.2 . Russians

HWEexpected_rus <- t(apply(allele_freq_rus, 1, function(x){
  M <- x["M"]^2
  MN <- 2*x["M"]*x["N"]
  N <- x["N"]^2
  return(cbind(M,MN,N))
  }))
colnames(HWEexpected_rus) <- c("M", "MN", "N")
HWEexpected_rus
             M        MN         N
[1,] 0.3826776 0.4718636 0.1454588

3.3.3 . Belgians

HWEexpected_bel <- t(apply(allele_freq_bel, 1, function(x){
  M <- x["M"]^2
  MN <- 2*x["M"]*x["N"]
  N <- x["N"]^2
  return(cbind(M,MN,N))
  }))
colnames(HWEexpected_bel) <- c("M", "MN", "N")
HWEexpected_bel
             M        MN         N
[1,] 0.2921228 0.4967221 0.2111551

3.3.4 . Papuans

HWEexpected_pap <- t(apply(allele_freq_pap, 1, function(x){
  M <- x["M"]^2
  MN <- 2*x["M"]*x["N"]
  N <- x["N"]^2
  return(cbind(M,MN,N))
  }))
colnames(HWEexpected_pap) <- c("M", "MN", "N")
HWEexpected_pap
          M     MN      N
[1,] 0.0361 0.3078 0.6561

3.4 . Chisquare test for observed vs expected HWE values

3.4.1 . Eskimos

# convert genotypes and proportions into lists for efficient tests
dat3_esk <- lapply(1:nrow(dat3[1,]), function(i){return(as.vector(dat3[i,]))})
HWEexpected_esk <- lapply(1:nrow(HWEexpected_esk), function(i){return(as.vector(HWEexpected_esk[i,]))
})
# Run HWE test
mapply(FUN = chisq.test, x = dat3_esk, p = HWEexpected_esk, SIMPLIFY = FALSE)
Chi-squared approximation may be incorrect
[[1]]

    Chi-squared test for given probabilities

data:  dots[[1L]][[1L]]
X-squared = 0.13408, df = 2, p-value = 0.9352

Chi-squared doesn’t like low values #### . Check Eskimo chi-squared against r-package for Hardy-Weinberg

library(HardyWeinberg)
Loading required package: mice
Loading required package: lattice
Loading required package: Rsolnp
eskobs <- c(AA = 475, AB = 89, BB = 5)
HWChisq(eskobs)
Expected counts below 5: chi-square approximation may be incorrect
Chi-square test with continuity correction for Hardy-Weinberg equilibrium (autosomal)
Chi2 =  0.01751215 DF =  1 p-value =  0.8947205 D =  -0.693761 f =  0.01535081 

This test isn’t happy either… To the best that I can tell, Eskimos are in HWE for blood groups ### . Russians

# convert genotypes and proportions into lists for efficient tests
dat3_rus <- lapply(1:nrow(dat3[2,]), function(i){return(as.vector(dat3[i,]))})
HWEexpected_rus <- lapply(1:nrow(HWEexpected_rus), function(i){return(as.vector(HWEexpected_rus[i,]))
})
# Run HWE test
mapply(FUN = chisq.test, x = dat3_rus, p = HWEexpected_rus, SIMPLIFY = FALSE)
[[1]]

    Chi-squared test for given probabilities

data:  dots[[1L]][[1L]]
X-squared = 497, df = 2, p-value < 2.2e-16

Russians are not in HWE

3.4.2 . Belgians

# convert genotypes and proportions into lists for efficient tests
dat3_bel <- lapply(1:nrow(dat3[3,]), function(i){return(as.vector(dat3[i,]))})
HWEexpected_bel <- lapply(1:nrow(HWEexpected_bel), function(i){return(as.vector(HWEexpected_bel[i,]))
})
# Run HWE test
mapply(FUN = chisq.test, x = dat3_bel, p = HWEexpected_bel, SIMPLIFY = FALSE)
[[1]]

    Chi-squared test for given probabilities

data:  dots[[1L]][[1L]]
X-squared = 816.64, df = 2, p-value < 2.2e-16

Belgians are not in HWE ### . Papuans

# convert genotypes and proportions into lists for efficient tests
dat3_pap <- lapply(1:nrow(dat3[4,]), function(i){return(as.vector(dat3[i,]))})
HWEexpected_pap <- lapply(1:nrow(HWEexpected_pap), function(i){return(as.vector(HWEexpected_pap[i,]))
})
# Run HWE test
mapply(FUN = chisq.test, x = dat3_pap, p = HWEexpected_pap, SIMPLIFY = FALSE)
[[1]]

    Chi-squared test for given probabilities

data:  dots[[1L]][[1L]]
X-squared = 10460, df = 2, p-value < 2.2e-16

Papuans are not in HWE

4 . Question 5 Drosophila genotypes

4.1 . Create data frame of observed values

dat <- data.frame(AA = c(100), Aa = c(0), aa = c(100), row.names = c("observed genotype counts"))
dat

4.2 . Calculate allele frequencies to work out expected genotype

proportions (e.g. 1 = p^2+q^2+2pq)
allele_freq_dro <- cbind(((2*dat$AA) + dat$Aa)/(2*rowSums(dat)),
  ((2*dat$aa) + dat$Aa)/(2*rowSums(dat)))
  colnames(allele_freq_dro) <- c("A", "a")
allele_freq_dro
                           A   a
observed genotype counts 0.5 0.5

4.3 . Calculate expected genotype proportions under Hardy-Weinberg Equillibrium

HWEexpected_dro <- t(apply(allele_freq_dro, 1, function(x){
  AA <- x["A"]^2
  Aa <- 2*x["A"]*x["a"]
  aa <- x["a"]^2
  return(cbind(AA, Aa, aa))
  }))
colnames(HWEexpected_dro) <- c("AA", "Aa", "aa")
HWEexpected_dro
                           AA  Aa   aa
observed genotype counts 0.25 0.5 0.25

4.4 . Calculate expected genotype proportions for an F1 generation

AA x aa cross

f1 <- 4 * allele_freq[,1] * allele_freq[,2]
f1
[1] 0.6182825

5 . Question 6 X-linked HWE

5.1 . Calculate allele frequencies to work out expected genotype

proportions (e.g. 1 = p^2+q^2+2pq)
p = 0.08
q = 1-p 
allele_freq <- data.frame("pp" = c(p^2), "2pq" = c(2*p*q), "qq"  = c(q^2), row.names = c("genotype frequency"))
allele_freq

6 . Question 7 Enzyme variation

4 alleles at a locus

6.1 . Create data frame of given frequencies

#A1 = p; A2 = q; A3 = r; A4 = s
allele_freq <- data.frame(p = c(.5), q = c(.3), r = c(.15), s = c(0.05), row.names = c("allele frequencies"))
allele_freq

6.2 . Calculate expected genotype proportions under Hardy-Weinberg Equillibrium

HWEexpected <- t(apply(allele_freq, 1, function(x){
  pp <- x["p"]^2
  pq <- 2*x["p"]*x["q"]
  pr <- 2*x["p"]*x["r"]
  ps <- 2*x["p"]*x["s"]
  qq <- x["q"]^2
  qr <- 2*x["q"]*x["r"]
  qs <- 2*x["q"]*x["s"]
  rr <- x["r"]^2
  rs <- 2*x["r"]*x["s"]
  ss <- x["s"]^2
  
  return(cbind(pp, pq, pr, ps, qq, qr, qs, rr, rs, ss))
  }))
colnames(HWEexpected) <- c("pp", "pq", "pr", "ps", "qq", "qr","qs", "rr", "rs", "ss")
HWEexpected
                     pp  pq   pr   ps   qq   qr   qs     rr    rs     ss
allele frequencies 0.25 0.3 0.15 0.05 0.09 0.09 0.03 0.0225 0.015 0.0025

6.3 . Heterozygote proportion

hetper <- rowSums(HWEexpected) - 
  (HWEexpected[,1] + 
   HWEexpected[,5] +
   HWEexpected[,8] +
   HWEexpected[,10])
hetper
allele frequencies 
             0.635 

6.4 . Specific A4 frequency determination

pop = 100
ss = HWEexpected[,10]
hets <- 2*(HWEexpected[,9]+HWEexpected[,7]+HWEexpected[,4])
print(pophets <- pop*hets)
[1] 19
print(popss <- pop*ss)
[1] 0.25

7 . Question 8 Variance ratio of inbreeding/panmictic

Using the drosophila population frequencies from question 5…

allele_freq_dro <- cbind(((2*dat$AA) + dat$Aa)/(2*rowSums(dat)),
  ((2*dat$aa) + dat$Aa)/(2*rowSums(dat)))
  colnames(allele_freq_dro) <- c("A", "a")
allele_freq_dro
                           A   a
observed genotype counts 0.5 0.5

7.1 . Calculate expected genotype proportions with inbreeding

f = 0.25
HWEexpected_inb <- t(apply(allele_freq_dro, 1, function(x){
  AA <- x["A"]^2 + f*x["A"]*x["a"]
  Aa <- 2*x["A"]*x["a"]*(1-f)
  aa <- x["a"]^2 + f*x["A"]*x["a"]
  return(cbind(AA, Aa, aa))
  }))
colnames(HWEexpected_inb) <- c("AA", "Aa", "aa")
HWEexpected_inb
                             AA    Aa     aa
observed genotype counts 0.3125 0.375 0.3125

7.2 . Compare ratios of HWE and inbreeding

falg = (HWEexpected_dro[,2]-HWEexpected_inb[,2])/HWEexpected_dro[,2]
falg
[1] 0.25
Sys.setenv(RSTUDIO_PANDOC="--- insert directory here ---")
LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6IAogICAgbnVtYmVyX3NlY3Rpb25zOiB5ZXMKICAgIHRoZW1lOiBjZXJ1bGVhbgogICAgdG9jOiB5ZXMKICBwZGZfZG9jdW1lbnQ6IGRlZmF1bHQKLS0tCiMgLiBRdWVzdGlvbiAxIHBnbS0xIGxvY3VzCiMjIC4gQ3JlYXRlIGRhdGEgZnJhbWUgb2Ygb2JzZXJ2ZWQgdmFsdWVzCmBgYHtyfQpkYXQgPC0gZGF0YS5mcmFtZShBQSA9IGMoNjM0KSwgQWEgPSBjKDM5MSksIGFhID0gYyg4NSksIHJvdy5uYW1lcyA9IGMoIm9ic2VydmVkIGdlbm90eXBlIGNvdW50cyIpKQpkYXQKYGBgCgojIyAuIENhbGN1bGF0ZSBhbGxlbGUgZnJlcXVlbmNpZXMgdG8gd29yayBvdXQgZXhwZWN0ZWQgZ2Vub3R5cGUKICAgIHByb3BvcnRpb25zIChlLmcuIDEgPSBwXjIrcV4yKzJwcSkKICAgIApgYGB7cn0KYWxsZWxlX2ZyZXEgPC0gY2JpbmQoKCgyKmRhdCRBQSkgKyBkYXQkQWEpLygyKnJvd1N1bXMoZGF0KSksCiAgKCgyKmRhdCRhYSkgKyBkYXQkQWEpLygyKnJvd1N1bXMoZGF0KSkpCiAgY29sbmFtZXMoYWxsZWxlX2ZyZXEpIDwtIGMoIkEiLCAiYSIpCmFsbGVsZV9mcmVxCmBgYAoKIyMgLiBDYWxjdWxhdGUgZXhwZWN0ZWQgZ2Vub3R5cGUgcHJvcG9ydGlvbnMgdW5kZXIgSGFyZHktV2VpbmJlcmcgRXF1aWxsaWJyaXVtCgpgYGB7cn0KSFdFZXhwZWN0ZWQgPC0gdChhcHBseShhbGxlbGVfZnJlcSwgMSwgZnVuY3Rpb24oeCl7CiAgQUEgPC0geFsiQSJdXjIKICBBYSA8LSAyKnhbIkEiXSp4WyJhIl0KICBhYSA8LSB4WyJhIl1eMgogIHJldHVybihjYmluZChBQSwgQWEsIGFhKSkKICB9KSkKSFdFZXhwZWN0ZWQKYGBgCgojIyAuIENoaXNxdWFyZSB0ZXN0IGZvciBvYnNlcnZlZCB2cyBleHBlY3RlZCBIV0UgdmFsdWVzCmBgYHtyfQojIGNvbnZlcnQgZ2Vub3R5cGVzIGFuZCBwcm9wb3J0aW9ucyBpbnRvIGxpc3RzIGZvciBlZmZpY2llbnQgdGVzdHMKZGF0IDwtIGxhcHBseSgxOm5yb3coZGF0KSwgZnVuY3Rpb24oaSkgcmV0dXJuKGFzLnZlY3RvcihkYXRbaSxdKSkpCkhXRWV4cGVjdGVkIDwtIGxhcHBseSgxOm5yb3coSFdFZXhwZWN0ZWQpLCBmdW5jdGlvbihpKXsKcmV0dXJuKGFzLnZlY3RvcihIV0VleHBlY3RlZFtpLF0pKQp9KQojIFJ1biBIV0UgdGVzdAptYXBwbHkoRlVOID0gY2hpc3EudGVzdCwgeCA9IGRhdCwgcCA9IEhXRWV4cGVjdGVkLCBTSU1QTElGWSA9IEZBTFNFKQpgYGAKVGhlIHAtdmFsdWUgaXMgZ3JlYXRlciB0aGFuIDAuMDUgc28gd2UgZmFpbCB0byByZWplY3QgdGhlIG51bGwgaHlwb3RoZXNpcyB0aGF0IHRoZSBwb3B1bGF0aW9uIGlzIGluIEhhcmR5LVdlaW5iZXJnIEVxdWlsaWJyaXVtCgojIC4gUXVlc3Rpb24gMiBTZXJ1bSBIYXB0b3R5cGVzIGluIEVneXB0aWFucwojIyAuIENyZWF0ZSBkYXRhIGZyYW1lIG9mIG9ic2VydmVkIHZhbHVlcwoKYGBge3J9CmRhdDIgPC0gZGF0YS5mcmFtZShwcCA9IGMoOSksIHBxID0gYygxMzUpLCBwciA9IGMoMiksIHFxID0gYyg3NSksICBxciA9IGMoMzkpLCByciA9IGMoMjUpLCByb3cubmFtZXMgPQogICAgICAgICAgICAgICAgICAgIGMoIm9ic2VydmVkIGdlbm90eXBlIGNvdW50cyIpKQpkYXQyCmBgYAoKIyMgLiBDYWxjdWxhdGUgYWxsZWxlIGZyZXF1ZW5jaWVzIHRvIHdvcmsgb3V0IGV4cGVjdGVkIGdlbm90eXBlCiAgICBwcm9wb3J0aW9ucyAoZS5nLiAxID0gcF4yK3FeMisycHEpCiAgICAKYGBge3J9CmFsbGVsZV9mcmVxIDwtIGNiaW5kKCgoMipkYXQyJHBwKSArIGRhdDIkcHEgKyBkYXQyJHByKS8oMipyb3dTdW1zKGRhdDIpKSwKICAgKCgyKmRhdDIkcXEpICsgZGF0MiRwcSArIGRhdDIkcXIpLygyKnJvd1N1bXMoZGF0MikpLAogICgoMipkYXQyJHJyKSArIGRhdDIkcHIgKyBkYXQyJHFyKS8oMipyb3dTdW1zKGRhdDIpKSkKY29sbmFtZXMoYWxsZWxlX2ZyZXEpIDwtIGMoInAiLCAicSIsICJyIikKcm93Lm5hbWVzKGFsbGVsZV9mcmVxKSA8LSBjKCJnZW5lIGZyZXF1ZW5jeSIpCmFsbGVsZV9mcmVxCmBgYAoKIyMgLiBDYWxjdWxhdGUgZXhwZWN0ZWQgZ2Vub3R5cGUgcHJvcG9ydGlvbnMgdW5kZXIgSGFyZHktV2VpbmJlcmcgRXF1aWxsaWJyaXVtCgpgYGB7cn0KSFdFZXhwZWN0ZWQgPC0gdChhcHBseShhbGxlbGVfZnJlcSwgMSwgZnVuY3Rpb24oeCl7CiAgcHAgPC0geFsicCJdXjIKICBwcSA8LSAyKnhbInAiXSp4WyJxIl0KICBwciA8LSAyKnhbInAiXSp4WyJyIl0KICBxcSA8LSB4WyJxIl1eMgogIHFyIDwtIDIqeFsicSJdKnhbInIiXQogIHJyIDwtIHhbInIiXV4yCiAgcmV0dXJuKGNiaW5kKHBwLCBwcSwgcHIsIHFxLCBxciwgcnIpKQogIH0pKQpjb2xuYW1lcyhIV0VleHBlY3RlZCkgPC0gYygicHAiLCAicHEiLCAicHIiLCAicXEiLCAicXIiLCAicnIiKQpIV0VleHBlY3RlZApgYGAKCiMjIC4gQ2hpc3F1YXJlIHRlc3QgZm9yIG9ic2VydmVkIHZzIGV4cGVjdGVkIEhXRSB2YWx1ZXMKYGBge3J9CiMgY29udmVydCBnZW5vdHlwZXMgYW5kIHByb3BvcnRpb25zIGludG8gbGlzdHMgZm9yIGVmZmljaWVudCB0ZXN0cwpkYXQyIDwtIGxhcHBseSgxOm5yb3coZGF0MiksIGZ1bmN0aW9uKGkpIHJldHVybihhcy52ZWN0b3IoZGF0MltpLF0pKSkKSFdFZXhwZWN0ZWQgPC0gbGFwcGx5KDE6bnJvdyhIV0VleHBlY3RlZCksIGZ1bmN0aW9uKGkpewpyZXR1cm4oYXMudmVjdG9yKEhXRWV4cGVjdGVkW2ksXSkpCn0pCiMgUnVuIEhXRSB0ZXN0Cm1hcHBseShGVU4gPSBjaGlzcS50ZXN0LCB4ID0gZGF0MiwgcCA9IEhXRWV4cGVjdGVkLCBTSU1QTElGWSA9IEZBTFNFKQpgYGAKcC12YWx1ZSBpcyBsZXNzIHRoYW4gMC4wNSBzbyB3ZSByZWplY3QgdGhlIG51bGwgb2YgSFdFLiAKCiMgLiBRdWVzdGlvbiAzIE0tTiBibG9vZCBncm91cHMKIyMgLiBDcmVhdGUgZGF0YSBmcmFtZSBvZiBvYnNlcnZlZCB2YWx1ZXMKYGBge3J9CmRhdDMgPC0gZGF0YS5mcmFtZShNID0gYyg0NzUsIDE5NSwgODk2LCAxNCksIE1OID0gYyg4OSwgMjE1LCAxNTU5LCA0OCksIE4gPSBjKDUsIDc5LCA2NDUsIDEzOCksIHJvdy5uYW1lcyA9IGMoIkVza2ltb3MiLCAiUnVzc2lhbnMiLCAiQmVsZ2lhbnMiLCAiUGFwdWFucyIpKQpkYXQzCmBgYAoKIyMgLiBDYWxjdWxhdGUgYWxsZWxlIGZyZXF1ZW5jaWVzIHRvIHdvcmsgb3V0IGV4cGVjdGVkIGdlbm90eXBlCiAgICBwcm9wb3J0aW9ucyAoZS5nLiAxID0gcF4yK3FeMisycHEpCiMjIyAuIEVza2ltb3MgICAgCmBgYHtyfQphbGxlbGVfZnJlcV9lc2sgPC0gY2JpbmQoKCgyKmRhdDNbMSwxXSkgKyBkYXQzWzEsMl0pLygyKnN1bShkYXQzWzEsXSkpLAogICgoMipkYXQzWzEsM10pICsgZGF0M1sxLDJdKS8oMipzdW0oZGF0M1sxLF0pKSkKICBjb2xuYW1lcyhhbGxlbGVfZnJlcV9lc2spIDwtIGMoIk0iLCAiTiIpCmFsbGVsZV9mcmVxX2VzawpgYGAKIyMjIC4gUnVzc2lhbnMKYGBge3J9CmFsbGVsZV9mcmVxX3J1cyA8LSBjYmluZCgoKDIqZGF0M1syLDFdKSArIGRhdDNbMiwyXSkvKDIqc3VtKGRhdDNbMixdKSksCiAgKCgyKmRhdDNbMiwzXSkgKyBkYXQzWzIsMl0pLygyKnN1bShkYXQzWzIsXSkpKQogIGNvbG5hbWVzKGFsbGVsZV9mcmVxX3J1cykgPC0gYygiTSIsICJOIikKYWxsZWxlX2ZyZXFfcnVzCmBgYAojIyMgLiBCZWxnaWFucwpgYGB7cn0KYWxsZWxlX2ZyZXFfYmVsIDwtIGNiaW5kKCgoMipkYXQzWzMsMV0pICsgZGF0M1szLDJdKS8oMipzdW0oZGF0M1szLF0pKSwKICAoKDIqZGF0M1szLDNdKSArIGRhdDNbMywyXSkvKDIqc3VtKGRhdDNbMyxdKSkpCiAgY29sbmFtZXMoYWxsZWxlX2ZyZXFfYmVsKSA8LSBjKCJNIiwgIk4iKQphbGxlbGVfZnJlcV9iZWwKYGBgCiMjIyAuIFBhcHVhbnMKYGBge3J9CmFsbGVsZV9mcmVxX3BhcCA8LSBjYmluZCgoKDIqZGF0M1s0LDFdKSArIGRhdDNbNCwyXSkvKDIqc3VtKGRhdDNbNCxdKSksCiAgKCgyKmRhdDNbNCwzXSkgKyBkYXQzWzQsMl0pLygyKnN1bShkYXQzWzQsXSkpKQogIGNvbG5hbWVzKGFsbGVsZV9mcmVxX3BhcCkgPC0gYygiTSIsICJOIikKYWxsZWxlX2ZyZXFfcGFwCmBgYAojIyAuIENhbGN1bGF0ZSBleHBlY3RlZCBnZW5vdHlwZSBwcm9wb3J0aW9ucyB1bmRlciBIYXJkeS1XZWluYmVyZyBFcXVpbGxpYnJpdW0KIyMjIC4gRXNraW1vcwpgYGB7cn0KSFdFZXhwZWN0ZWRfZXNrIDwtIHQoYXBwbHkoYWxsZWxlX2ZyZXFfZXNrLCAxLCBmdW5jdGlvbih4KXsKICBNIDwtIHhbIk0iXV4yCiAgTU4gPC0gMip4WyJNIl0qeFsiTiJdCiAgTiA8LSB4WyJOIl1eMgogIHJldHVybihjYmluZChNLE1OLE4pKQogIH0pKQpjb2xuYW1lcyhIV0VleHBlY3RlZF9lc2spIDwtIGMoIk0iLCAiTU4iLCAiTiIpCkhXRWV4cGVjdGVkX2VzawpgYGAKIyMjIC4gUnVzc2lhbnMKYGBge3J9CkhXRWV4cGVjdGVkX3J1cyA8LSB0KGFwcGx5KGFsbGVsZV9mcmVxX3J1cywgMSwgZnVuY3Rpb24oeCl7CiAgTSA8LSB4WyJNIl1eMgogIE1OIDwtIDIqeFsiTSJdKnhbIk4iXQogIE4gPC0geFsiTiJdXjIKICByZXR1cm4oY2JpbmQoTSxNTixOKSkKICB9KSkKY29sbmFtZXMoSFdFZXhwZWN0ZWRfcnVzKSA8LSBjKCJNIiwgIk1OIiwgIk4iKQpIV0VleHBlY3RlZF9ydXMKYGBgCiMjIyAuIEJlbGdpYW5zCmBgYHtyfQpIV0VleHBlY3RlZF9iZWwgPC0gdChhcHBseShhbGxlbGVfZnJlcV9iZWwsIDEsIGZ1bmN0aW9uKHgpewogIE0gPC0geFsiTSJdXjIKICBNTiA8LSAyKnhbIk0iXSp4WyJOIl0KICBOIDwtIHhbIk4iXV4yCiAgcmV0dXJuKGNiaW5kKE0sTU4sTikpCiAgfSkpCmNvbG5hbWVzKEhXRWV4cGVjdGVkX2JlbCkgPC0gYygiTSIsICJNTiIsICJOIikKSFdFZXhwZWN0ZWRfYmVsCmBgYAojIyMgLiBQYXB1YW5zCmBgYHtyfQpIV0VleHBlY3RlZF9wYXAgPC0gdChhcHBseShhbGxlbGVfZnJlcV9wYXAsIDEsIGZ1bmN0aW9uKHgpewogIE0gPC0geFsiTSJdXjIKICBNTiA8LSAyKnhbIk0iXSp4WyJOIl0KICBOIDwtIHhbIk4iXV4yCiAgcmV0dXJuKGNiaW5kKE0sTU4sTikpCiAgfSkpCmNvbG5hbWVzKEhXRWV4cGVjdGVkX3BhcCkgPC0gYygiTSIsICJNTiIsICJOIikKSFdFZXhwZWN0ZWRfcGFwCmBgYAoKIyMgLiBDaGlzcXVhcmUgdGVzdCBmb3Igb2JzZXJ2ZWQgdnMgZXhwZWN0ZWQgSFdFIHZhbHVlcwojIyMgLiBFc2tpbW9zCmBgYHtyfQojIGNvbnZlcnQgZ2Vub3R5cGVzIGFuZCBwcm9wb3J0aW9ucyBpbnRvIGxpc3RzIGZvciBlZmZpY2llbnQgdGVzdHMKZGF0M19lc2sgPC0gbGFwcGx5KDE6bnJvdyhkYXQzWzEsXSksIGZ1bmN0aW9uKGkpe3JldHVybihhcy52ZWN0b3IoZGF0M1tpLF0pKX0pCkhXRWV4cGVjdGVkX2VzayA8LSBsYXBwbHkoMTpucm93KEhXRWV4cGVjdGVkX2VzayksIGZ1bmN0aW9uKGkpe3JldHVybihhcy52ZWN0b3IoSFdFZXhwZWN0ZWRfZXNrW2ksXSkpCn0pCiMgUnVuIEhXRSB0ZXN0Cm1hcHBseShGVU4gPSBjaGlzcS50ZXN0LCB4ID0gZGF0M19lc2ssIHAgPSBIV0VleHBlY3RlZF9lc2ssIFNJTVBMSUZZID0gRkFMU0UpCgpgYGAKQ2hpLXNxdWFyZWQgZG9lc24ndCBsaWtlIGxvdyB2YWx1ZXMKIyMjIyAuIENoZWNrIEVza2ltbyBjaGktc3F1YXJlZCBhZ2FpbnN0IHItcGFja2FnZSBmb3IgSGFyZHktV2VpbmJlcmcKYGBge3J9CmxpYnJhcnkoSGFyZHlXZWluYmVyZykKZXNrb2JzIDwtIGMoQUEgPSA0NzUsIEFCID0gODksIEJCID0gNSkKSFdDaGlzcShlc2tvYnMpCmBgYApUaGlzIHRlc3QgaXNuJ3QgaGFwcHkgZWl0aGVyLi4uClRvIHRoZSBiZXN0IHRoYXQgSSBjYW4gdGVsbCwgRXNraW1vcyBhcmUgaW4gSFdFIGZvciBibG9vZCBncm91cHMKIyMjIC4gUnVzc2lhbnMKYGBge3J9CiMgY29udmVydCBnZW5vdHlwZXMgYW5kIHByb3BvcnRpb25zIGludG8gbGlzdHMgZm9yIGVmZmljaWVudCB0ZXN0cwpkYXQzX3J1cyA8LSBsYXBwbHkoMTpucm93KGRhdDNbMixdKSwgZnVuY3Rpb24oaSl7cmV0dXJuKGFzLnZlY3RvcihkYXQzW2ksXSkpfSkKSFdFZXhwZWN0ZWRfcnVzIDwtIGxhcHBseSgxOm5yb3coSFdFZXhwZWN0ZWRfcnVzKSwgZnVuY3Rpb24oaSl7cmV0dXJuKGFzLnZlY3RvcihIV0VleHBlY3RlZF9ydXNbaSxdKSkKfSkKIyBSdW4gSFdFIHRlc3QKbWFwcGx5KEZVTiA9IGNoaXNxLnRlc3QsIHggPSBkYXQzX3J1cywgcCA9IEhXRWV4cGVjdGVkX3J1cywgU0lNUExJRlkgPSBGQUxTRSkKYGBgClJ1c3NpYW5zIGFyZSBub3QgaW4gSFdFCgojIyMgLiBCZWxnaWFucwpgYGB7cn0KIyBjb252ZXJ0IGdlbm90eXBlcyBhbmQgcHJvcG9ydGlvbnMgaW50byBsaXN0cyBmb3IgZWZmaWNpZW50IHRlc3RzCmRhdDNfYmVsIDwtIGxhcHBseSgxOm5yb3coZGF0M1szLF0pLCBmdW5jdGlvbihpKXtyZXR1cm4oYXMudmVjdG9yKGRhdDNbaSxdKSl9KQpIV0VleHBlY3RlZF9iZWwgPC0gbGFwcGx5KDE6bnJvdyhIV0VleHBlY3RlZF9iZWwpLCBmdW5jdGlvbihpKXtyZXR1cm4oYXMudmVjdG9yKEhXRWV4cGVjdGVkX2JlbFtpLF0pKQp9KQojIFJ1biBIV0UgdGVzdAptYXBwbHkoRlVOID0gY2hpc3EudGVzdCwgeCA9IGRhdDNfYmVsLCBwID0gSFdFZXhwZWN0ZWRfYmVsLCBTSU1QTElGWSA9IEZBTFNFKQpgYGAKQmVsZ2lhbnMgYXJlIG5vdCBpbiBIV0UKIyMjIC4gUGFwdWFucwpgYGB7cn0KIyBjb252ZXJ0IGdlbm90eXBlcyBhbmQgcHJvcG9ydGlvbnMgaW50byBsaXN0cyBmb3IgZWZmaWNpZW50IHRlc3RzCmRhdDNfcGFwIDwtIGxhcHBseSgxOm5yb3coZGF0M1s0LF0pLCBmdW5jdGlvbihpKXtyZXR1cm4oYXMudmVjdG9yKGRhdDNbaSxdKSl9KQpIV0VleHBlY3RlZF9wYXAgPC0gbGFwcGx5KDE6bnJvdyhIV0VleHBlY3RlZF9wYXApLCBmdW5jdGlvbihpKXtyZXR1cm4oYXMudmVjdG9yKEhXRWV4cGVjdGVkX3BhcFtpLF0pKQp9KQojIFJ1biBIV0UgdGVzdAptYXBwbHkoRlVOID0gY2hpc3EudGVzdCwgeCA9IGRhdDNfcGFwLCBwID0gSFdFZXhwZWN0ZWRfcGFwLCBTSU1QTElGWSA9IEZBTFNFKQpgYGAKUGFwdWFucyBhcmUgbm90IGluIEhXRQoKIyAuIFF1ZXN0aW9uIDUgRHJvc29waGlsYSBnZW5vdHlwZXMKCiMjIC4gQ3JlYXRlIGRhdGEgZnJhbWUgb2Ygb2JzZXJ2ZWQgdmFsdWVzCmBgYHtyfQpkYXQgPC0gZGF0YS5mcmFtZShBQSA9IGMoMTAwKSwgQWEgPSBjKDApLCBhYSA9IGMoMTAwKSwgcm93Lm5hbWVzID0gYygib2JzZXJ2ZWQgZ2Vub3R5cGUgY291bnRzIikpCmRhdApgYGAKCiMjIC4gQ2FsY3VsYXRlIGFsbGVsZSBmcmVxdWVuY2llcyB0byB3b3JrIG91dCBleHBlY3RlZCBnZW5vdHlwZQogICAgcHJvcG9ydGlvbnMgKGUuZy4gMSA9IHBeMitxXjIrMnBxKQogICAgCmBgYHtyfQphbGxlbGVfZnJlcV9kcm8gPC0gY2JpbmQoKCgyKmRhdCRBQSkgKyBkYXQkQWEpLygyKnJvd1N1bXMoZGF0KSksCiAgKCgyKmRhdCRhYSkgKyBkYXQkQWEpLygyKnJvd1N1bXMoZGF0KSkpCiAgY29sbmFtZXMoYWxsZWxlX2ZyZXFfZHJvKSA8LSBjKCJBIiwgImEiKQphbGxlbGVfZnJlcV9kcm8KYGBgCgojIyAuIENhbGN1bGF0ZSBleHBlY3RlZCBnZW5vdHlwZSBwcm9wb3J0aW9ucyB1bmRlciBIYXJkeS1XZWluYmVyZyBFcXVpbGxpYnJpdW0KCmBgYHtyfQpIV0VleHBlY3RlZF9kcm8gPC0gdChhcHBseShhbGxlbGVfZnJlcV9kcm8sIDEsIGZ1bmN0aW9uKHgpewogIEFBIDwtIHhbIkEiXV4yCiAgQWEgPC0gMip4WyJBIl0qeFsiYSJdCiAgYWEgPC0geFsiYSJdXjIKICByZXR1cm4oY2JpbmQoQUEsIEFhLCBhYSkpCiAgfSkpCmNvbG5hbWVzKEhXRWV4cGVjdGVkX2RybykgPC0gYygiQUEiLCAiQWEiLCAiYWEiKQpIV0VleHBlY3RlZF9kcm8KYGBgCgojIyAuIENhbGN1bGF0ZSBleHBlY3RlZCBnZW5vdHlwZSBwcm9wb3J0aW9ucyBmb3IgYW4gRjEgZ2VuZXJhdGlvbgpBQSB4IGFhIGNyb3NzCmBgYHtyfQpmMSA8LSA0ICogYWxsZWxlX2ZyZXFbLDFdICogYWxsZWxlX2ZyZXFbLDJdCmYxCmBgYAoKIyAuIFF1ZXN0aW9uIDYgWC1saW5rZWQgSFdFCgoKIyMgLiBDYWxjdWxhdGUgYWxsZWxlIGZyZXF1ZW5jaWVzIHRvIHdvcmsgb3V0IGV4cGVjdGVkIGdlbm90eXBlCiAgICBwcm9wb3J0aW9ucyAoZS5nLiAxID0gcF4yK3FeMisycHEpCiAgICAKYGBge3J9CnAgPSAwLjA4CnEgPSAxLXAgCgphbGxlbGVfZnJlcSA8LSBkYXRhLmZyYW1lKCJwcCIgPSBjKHBeMiksICIycHEiID0gYygyKnAqcSksICJxcSIgID0gYyhxXjIpLCByb3cubmFtZXMgPSBjKCJnZW5vdHlwZSBmcmVxdWVuY3kiKSkKYWxsZWxlX2ZyZXEKYGBgCgojIC4gUXVlc3Rpb24gNyBFbnp5bWUgdmFyaWF0aW9uCjQgYWxsZWxlcyBhdCBhIGxvY3VzCgojIyAuIENyZWF0ZSBkYXRhIGZyYW1lIG9mIGdpdmVuIGZyZXF1ZW5jaWVzCgpgYGB7cn0KI0ExID0gcDsgQTIgPSBxOyBBMyA9IHI7IEE0ID0gcwphbGxlbGVfZnJlcSA8LSBkYXRhLmZyYW1lKHAgPSBjKC41KSwgcSA9IGMoLjMpLCByID0gYyguMTUpLCBzID0gYygwLjA1KSwgcm93Lm5hbWVzID0gYygiYWxsZWxlIGZyZXF1ZW5jaWVzIikpCmFsbGVsZV9mcmVxCmBgYAoKCiMjIC4gQ2FsY3VsYXRlIGV4cGVjdGVkIGdlbm90eXBlIHByb3BvcnRpb25zIHVuZGVyIEhhcmR5LVdlaW5iZXJnIEVxdWlsbGlicml1bQoKYGBge3J9CkhXRWV4cGVjdGVkIDwtIHQoYXBwbHkoYWxsZWxlX2ZyZXEsIDEsIGZ1bmN0aW9uKHgpewogIHBwIDwtIHhbInAiXV4yCiAgcHEgPC0gMip4WyJwIl0qeFsicSJdCiAgcHIgPC0gMip4WyJwIl0qeFsiciJdCiAgcHMgPC0gMip4WyJwIl0qeFsicyJdCiAgcXEgPC0geFsicSJdXjIKICBxciA8LSAyKnhbInEiXSp4WyJyIl0KICBxcyA8LSAyKnhbInEiXSp4WyJzIl0KICByciA8LSB4WyJyIl1eMgogIHJzIDwtIDIqeFsiciJdKnhbInMiXQogIHNzIDwtIHhbInMiXV4yCiAgCiAgcmV0dXJuKGNiaW5kKHBwLCBwcSwgcHIsIHBzLCBxcSwgcXIsIHFzLCByciwgcnMsIHNzKSkKICB9KSkKY29sbmFtZXMoSFdFZXhwZWN0ZWQpIDwtIGMoInBwIiwgInBxIiwgInByIiwgInBzIiwgInFxIiwgInFyIiwicXMiLCAicnIiLCAicnMiLCAic3MiKQpIV0VleHBlY3RlZApgYGAKCiMjIC4gSGV0ZXJvenlnb3RlIHByb3BvcnRpb24KYGBge3J9CmhldHBlciA8LSByb3dTdW1zKEhXRWV4cGVjdGVkKSAtIAogIChIV0VleHBlY3RlZFssMV0gKyAKICAgSFdFZXhwZWN0ZWRbLDVdICsKICAgSFdFZXhwZWN0ZWRbLDhdICsKICAgSFdFZXhwZWN0ZWRbLDEwXSkKaGV0cGVyCmBgYAojIyAuIFNwZWNpZmljIEE0IGZyZXF1ZW5jeSBkZXRlcm1pbmF0aW9uCgpgYGB7cn0KcG9wID0gMTAwCnNzID0gSFdFZXhwZWN0ZWRbLDEwXQpoZXRzIDwtIDIqKEhXRWV4cGVjdGVkWyw5XStIV0VleHBlY3RlZFssN10rSFdFZXhwZWN0ZWRbLDRdKQpwcmludChwb3BoZXRzIDwtIHBvcCpoZXRzKQpwcmludChwb3BzcyA8LSBwb3Aqc3MpCmBgYAoKIyAuIFF1ZXN0aW9uIDggVmFyaWFuY2UgcmF0aW8gb2YgaW5icmVlZGluZy9wYW5taWN0aWMKClVzaW5nIHRoZSBkcm9zb3BoaWxhIHBvcHVsYXRpb24gZnJlcXVlbmNpZXMgZnJvbSBxdWVzdGlvbiA1Li4uCgpgYGB7cn0KYWxsZWxlX2ZyZXFfZHJvIDwtIGNiaW5kKCgoMipkYXQkQUEpICsgZGF0JEFhKS8oMipyb3dTdW1zKGRhdCkpLAogICgoMipkYXQkYWEpICsgZGF0JEFhKS8oMipyb3dTdW1zKGRhdCkpKQogIGNvbG5hbWVzKGFsbGVsZV9mcmVxX2RybykgPC0gYygiQSIsICJhIikKYWxsZWxlX2ZyZXFfZHJvCmBgYAoKIyMgLiBDYWxjdWxhdGUgZXhwZWN0ZWQgZ2Vub3R5cGUgcHJvcG9ydGlvbnMgd2l0aCBpbmJyZWVkaW5nCgpgYGB7cn0KZiA9IDAuMjUKSFdFZXhwZWN0ZWRfaW5iIDwtIHQoYXBwbHkoYWxsZWxlX2ZyZXFfZHJvLCAxLCBmdW5jdGlvbih4KXsKICBBQSA8LSB4WyJBIl1eMiArIGYqeFsiQSJdKnhbImEiXQogIEFhIDwtIDIqeFsiQSJdKnhbImEiXSooMS1mKQogIGFhIDwtIHhbImEiXV4yICsgZip4WyJBIl0qeFsiYSJdCiAgcmV0dXJuKGNiaW5kKEFBLCBBYSwgYWEpKQogIH0pKQpjb2xuYW1lcyhIV0VleHBlY3RlZF9pbmIpIDwtIGMoIkFBIiwgIkFhIiwgImFhIikKSFdFZXhwZWN0ZWRfaW5iCmBgYAojIyAuIENvbXBhcmUgcmF0aW9zIG9mIEhXRSBhbmQgaW5icmVlZGluZwpgYGB7cn0KZmFsZyA9IChIV0VleHBlY3RlZF9kcm9bLDJdLUhXRWV4cGVjdGVkX2luYlssMl0pL0hXRWV4cGVjdGVkX2Ryb1ssMl0KZmFsZwpgYGAKYGBge3J9ClN5cy5zZXRlbnYoUlNUVURJT19QQU5ET0M9Ii0tLSBpbnNlcnQgZGlyZWN0b3J5IGhlcmUgLS0tIikKYGBgCgo=