Genotype data and sample information

We will use genotyping data from the 1000 genomes project. Specifically we will use genotypes from Yoruba individuals from Nigeria

Read Samples

Read in the identifiers of the samples. Each sample is an immortalized lymphoblastoid cell line derived from a different Yoruba individual.

# use 'as.character' to make sure we have the sample names as a vector of character strings (rather than
# a factor)
sample.tab <- read.table("samples.txt", header=F)
sample.names <- as.character(sample.tab$V1)
head(sample.names)
[1] "NA18520" "NA19225" "NA19143" "NA19201" "NA19144" "NA19147"
# just cell line sample names, NA = nucleic acid

Read Genotypes

Read in SNP genotypes for each of the samples. For simplicity, we will only use SNPs on chromosome 22. The first 4 columns give information about the SNP, the remaining columns give the genotypes for each sample. The genotypes are coded as the number of copies of allele2 that each individual carries and can therefore be 0, 1, or 2. For convenience, also create a ‘genotype matrix’ that only contains columns with genotype counts.

genotypes.tab <- read.table("chr22_genotypes.txt", header=T)
head(genotypes.tab)

# all the individuals have geneotypes
# 0 = homozygous for reference allele (most common)
# 1 = heterozygous for reference allele (aka non-refernece allele or not the same in rerence genome)
# 2 = homozygous for non-refernce allele
# if there are 2 bases in reference genome (allele 1) but 1 in sample (allele 2), its an indel

genotype.matrix <- genotypes.tab[,sample.names]
head(genotype.matrix)
NA

Analyze genotype data

Here are a few questions to get people familiar with the genotype data

Q: How many samples are there?

n.samples <- length(sample.names)
n.samples
[1] 53

Q: what is the chromosomal position and alleles of SNP rs55926024?

snp.row <- genotypes.tab$SNP.ID == "rs55926024"
snp.row
   [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  [38] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
  [75] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [112] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [149] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [186] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [223] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [260] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [297] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [334] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [371] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [408] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [445] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [482] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [519] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [556] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [593] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [630] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [667] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [704] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [741] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [778] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [815] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [852] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [889] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [926] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
 [963] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
[1000] FALSE
 [ reached getOption("max.print") -- omitted 263161 entries ]

Q: How many individuals are heterozygous for SNP rs55926024?

sum(genotype.matrix[snp.row,] == 1)
[1] 22
# just count number of columns where someone has a "1"

Q: What is the frequency of allele2 for rs55926024 in our samples?

total.alleles <- n.samples * 2
# multiply times 2 since looking at a diploid (2 allele copies)
sum(genotype.matrix[snp.row,]) / total.alleles
[1] 0.3584906
# since less frequent allele, sometimes called minor or (minor allele frequency = MAF (?))

Gene expression data

We will use RNA-seq gene expression data from the GEUVADIS project. The data are from the same Yoruba cell lines that we have genotypes for. The reads have already been mapped to the genome and gene expression has been estimated using the transcripts-per-million (TPM) measure. (For an explanation of TPM see http://www.rna-seqblog.com/rpkm-fpkm-and-tpm-clearly-explained/).

Read in mapped RNA-seq read counts for each gene. The first columns 5 give information about the gene. The subsequent columns that start with “NA” (e.g. NA18520) contain TPM estimates for each sample in the study.

# VCF = file that genetoying info is provided in. Has a lot of information in it


tpm.expr.tab <- read.table("gene_expr_tpm.txt", header=T)
head(tpm.expr.tab)
NA

Analyze gene expression values

Q: How many genes are in the gene expression table?

nrow(tpm.expr.tab)
[1] 63677

This is a lot of ‘genes’! The Ensembl ‘ENSG’ gene list contains many pseudo-genes, and low-expression lncRNAs etc.

Calculate mean expression across samples, then make a histogram of log mean TPM values for genes that have mean TPM > 0.0.

# so let's just get the ones that have the biggest expression
# take a mean acorss each row (gene) from the different cell lines
# extract just the expression data:
all.tpm.matrix <- tpm.expr.tab[,sample.names]

# compute mean expression and plog log mean TPM
# gene expression has a huge range, so if you want to look at that distrubution, better to use Log. So first filter out gene with 0 exprssion (we don't care about those)
mean.expr <- apply(all.tpm.matrix, 1, mean)
f <- mean.expr > 0.0
hist(log(mean.expr[f]), breaks=100)


# x axis = log TPM
# so things below 0 are probalby not expressed

The mean expression distribution is bimodal, with a large number of low-expression genes.

Q: How many genes have mean TPM values > 1.0?

# Take genes with expression value of TPM >1
sum(mean.expr > 1)
[1] 16279

This is a reasonable number of genes to consider expressed in this cell type (lymphoblastoid cell lines). So lets discard all genes with TPM < 1.0 from further analyses.

mean.expr <- apply(all.tpm.matrix, 1, mean)
f <- mean.expr > 1
hist(log(mean.expr[f]), breaks=100)

Other data pre-processing

There are additional steps we could take when processing the gene expression and genotype data.

identifying eQTLs

Get a set of genes that are on chr22 and that have TPM > 1.0

f <- (tpm.expr.tab$CHROM == "chr22") & (mean.expr > 1.0)
chr22.tpm.expr.tab <- tpm.expr.tab[f,]
chr22.tpm.matrix <- tpm.expr.tab[f,sample.names] 

head(chr22.tpm.matrix)
# now every cell line has genes ewith expression values

Plot the expression of gene ENSG00000218537 (MIF-AS1) as a function of the genotype of the SNP rs5760108.

# gene expression for one gene
# gene ENSG, SNP rs###
expr <- unlist(chr22.tpm.matrix[chr22.tpm.expr.tab$GENE.NAME == "ENSG00000218537",])
genos <- unlist(genotype.matrix[genotypes.tab$SNP.ID == "rs5760108",])

plot(jitter(genos), expr, xlab="genotype", ylab="gene expression (TPM)")

# jitter adds noise so you can see more details of your plot "avoid overplotting"

Fit a linear model, using expression as the response and genotype as the predictor

mdl <- lm(expr ~ genos)
summary(mdl)

Call:
lm(formula = expr ~ genos)

Residuals:
     Min       1Q   Median       3Q      Max 
-1.44888 -0.73025 -0.04898  0.66507  2.46593 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept)   0.1976     0.2372   0.833    0.409    
genos         1.2513     0.1841   6.797 1.14e-08 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.9117 on 51 degrees of freedom
Multiple R-squared:  0.4753,    Adjusted R-squared:  0.465 
F-statistic:  46.2 on 1 and 51 DF,  p-value: 1.138e-08

Get the slope (often called effect size or Beta) and p-value from the regression, and add the fit line to the genotype vs. expression plot.

intercept <- mdl$coefficients[1]
beta <- mdl$coefficients[2]
s <- summary(mdl)
p.val <- s$coefficients["genos","Pr(>|t|)"]

plot(jitter(genos), expr, xlab="genotype", ylab="gene expression (TPM)")
abline(a=intercept, b=beta, col="red")

Now lets test all SNPs that are close (within 50kb) of the gene ENSG00000218537 for association.

First get the genotypes of all of the nearby SNPs.

larger windows better for larger sample sizes

Why do we test SNPs only around the gene, and not throughout the whole genome?

We want to enrich for near the gene because that’s where the regulatory elements are

Whole genome would be nice, but that is very challenging. some people do it– and they find trans-acting eQTLs

# cis-alleles within 50kb of the gene to identify regulatory elements to test all the SNPs that are -50 and +50kb of the gene
gene.row <- which(chr22.tpm.expr.tab$GENE.NAME == "ENSG00000218537")
start <- chr22.tpm.expr.tab$GENE.START[gene.row] - 50000
end <- chr22.tpm.expr.tab$GENE.END[gene.row] + 50000

snp.rows <- which(genotypes.tab$CHROM.POS >= start & genotypes.tab$CHROM.POS <= end)

genotypes <- genotype.matrix[snp.rows,]
n.snps <- nrow(genotypes)

n.snps
[1] 1081

Next perform linear regression of the genoypes of each SNP against the expression of the gene and make a histogram of the p-values.

p.vals <- rep(NA, n.snps)

for(i in seq(1, n.snps)) {
  genos <- unlist(genotypes[i,])
  mdl <- lm(expr ~ genos)
  s <- summary(mdl)
  p.vals[i] <- s$coefficients["genos","Pr(>|t|)"]
}

hist(p.vals)

Plot the genomic position of the SNPs (x-axis) against their -log10 p-values (y-axis)

pos <- genotypes.tab$CHROM.POS[snp.rows]
plot(pos, -log10(p.vals), ylab="-log10(p-value)", xlab="chr22 position")
# add the position of the gene
lines(x=c(chr22.tpm.expr.tab$GENE.START[gene.row], chr22.tpm.expr.tab$GENE.END[gene.row]), y=c(0,0), 
         col="blue", lwd=4)

LS0tCnRpdGxlOiAiQklPTTI2MiAtIGVRVEwgbWFwcGluZyIKb3V0cHV0OiBodG1sX25vdGVib29rCi0tLQoKIyMgR2Vub3R5cGUgZGF0YSBhbmQgc2FtcGxlIGluZm9ybWF0aW9uCgpXZSB3aWxsIHVzZSBnZW5vdHlwaW5nIGRhdGEgZnJvbSB0aGUgMTAwMCBnZW5vbWVzIHByb2plY3QuIFNwZWNpZmljYWxseSB3ZSB3aWxsIHVzZSBnZW5vdHlwZXMgZnJvbSBZb3J1YmEgaW5kaXZpZHVhbHMgZnJvbSBOaWdlcmlhCgojIyMgUmVhZCBTYW1wbGVzCgpSZWFkIGluIHRoZSBpZGVudGlmaWVycyBvZiB0aGUgc2FtcGxlcy4gRWFjaCBzYW1wbGUgaXMgYW4gaW1tb3J0YWxpemVkIGx5bXBob2JsYXN0b2lkIGNlbGwgbGluZSBkZXJpdmVkIGZyb20gYSBkaWZmZXJlbnQgWW9ydWJhIGluZGl2aWR1YWwuCgpgYGB7cn0KIyB1c2UgJ2FzLmNoYXJhY3RlcicgdG8gbWFrZSBzdXJlIHdlIGhhdmUgdGhlIHNhbXBsZSBuYW1lcyBhcyBhIHZlY3RvciBvZiBjaGFyYWN0ZXIgc3RyaW5ncyAocmF0aGVyIHRoYW4KIyBhIGZhY3RvcikKc2FtcGxlLnRhYiA8LSByZWFkLnRhYmxlKCJzYW1wbGVzLnR4dCIsIGhlYWRlcj1GKQpzYW1wbGUubmFtZXMgPC0gYXMuY2hhcmFjdGVyKHNhbXBsZS50YWIkVjEpCmhlYWQoc2FtcGxlLm5hbWVzKQojIGp1c3QgY2VsbCBsaW5lIHNhbXBsZSBuYW1lcywgTkEgPSBudWNsZWljIGFjaWQKYGBgCgojIyMgUmVhZCBHZW5vdHlwZXMKClJlYWQgaW4gU05QIGdlbm90eXBlcyBmb3IgZWFjaCBvZiB0aGUgc2FtcGxlcy4gRm9yIHNpbXBsaWNpdHksIHdlIHdpbGwgb25seSB1c2UgU05QcyBvbiBjaHJvbW9zb21lIDIyLiBUaGUgZmlyc3QgNCBjb2x1bW5zIGdpdmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlIFNOUCwgdGhlIHJlbWFpbmluZyBjb2x1bW5zIGdpdmUgdGhlIGdlbm90eXBlcyBmb3IgZWFjaCBzYW1wbGUuIFRoZSBnZW5vdHlwZXMgYXJlIGNvZGVkIGFzIHRoZSBudW1iZXIgb2YgY29waWVzIG9mIGFsbGVsZTIgdGhhdCBlYWNoIGluZGl2aWR1YWwgY2FycmllcyBhbmQgY2FuIHRoZXJlZm9yZSBiZSAwLCAxLCBvciAyLiBGb3IgY29udmVuaWVuY2UsIGFsc28gY3JlYXRlIGEgJ2dlbm90eXBlIG1hdHJpeCcgdGhhdCBvbmx5IGNvbnRhaW5zIGNvbHVtbnMgd2l0aCBnZW5vdHlwZSBjb3VudHMuCgpgYGB7cn0KZ2Vub3R5cGVzLnRhYiA8LSByZWFkLnRhYmxlKCJjaHIyMl9nZW5vdHlwZXMudHh0IiwgaGVhZGVyPVQpCmhlYWQoZ2Vub3R5cGVzLnRhYikKCiMgYWxsIHRoZSBpbmRpdmlkdWFscyBoYXZlIGdlbmVvdHlwZXMKIyAwID0gaG9tb3p5Z291cyBmb3IgcmVmZXJlbmNlIGFsbGVsZSAobW9zdCBjb21tb24pCiMgMSA9IGhldGVyb3p5Z291cyBmb3IgcmVmZXJlbmNlIGFsbGVsZSAoYWthIG5vbi1yZWZlcm5lY2UgYWxsZWxlIG9yIG5vdCB0aGUgc2FtZSBpbiByZXJlbmNlIGdlbm9tZSkKIyAyID0gaG9tb3p5Z291cyBmb3Igbm9uLXJlZmVybmNlIGFsbGVsZQojIGlmIHRoZXJlIGFyZSAyIGJhc2VzIGluIHJlZmVyZW5jZSBnZW5vbWUgKGFsbGVsZSAxKSBidXQgMSBpbiBzYW1wbGUgKGFsbGVsZSAyKSwgaXRzIGFuIGluZGVsCgpnZW5vdHlwZS5tYXRyaXggPC0gZ2Vub3R5cGVzLnRhYlssc2FtcGxlLm5hbWVzXQpoZWFkKGdlbm90eXBlLm1hdHJpeCkKCmBgYAoKIyMjIEFuYWx5emUgZ2Vub3R5cGUgZGF0YQoKSGVyZSBhcmUgYSBmZXcgcXVlc3Rpb25zIHRvIGdldCBwZW9wbGUgZmFtaWxpYXIgd2l0aCB0aGUgZ2Vub3R5cGUgZGF0YQoKUTogSG93IG1hbnkgc2FtcGxlcyBhcmUgdGhlcmU/CgpgYGB7cn0Kbi5zYW1wbGVzIDwtIGxlbmd0aChzYW1wbGUubmFtZXMpCm4uc2FtcGxlcwpgYGAKClE6IHdoYXQgaXMgdGhlIGNocm9tb3NvbWFsIHBvc2l0aW9uIGFuZCBhbGxlbGVzIG9mIFNOUCByczU1OTI2MDI0PwoKYGBge3J9CiMgZm9jdXMgb24gYSBzcGVjaWZpYyBTTlAKc25wLnJvdyA8LSBnZW5vdHlwZXMudGFiJFNOUC5JRCA9PSAicnM1NTkyNjAyNCIKZ2Vub3R5cGVzLnRhYltzbnAucm93LCBjKCJDSFJPTSIsICJDSFJPTS5QT1MiLCAiQUxMRUxFMSIsICJBTExFTEUyIildCgojIGNocm9tbyAyMiwgfjE2TSBwb3NpdGlvbgpgYGAKClE6IEhvdyBtYW55IGluZGl2aWR1YWxzIGFyZSBoZXRlcm96eWdvdXMgZm9yIFNOUCByczU1OTI2MDI0PwoKYGBge3J9CnN1bShnZW5vdHlwZS5tYXRyaXhbc25wLnJvdyxdID09IDEpCiMganVzdCBjb3VudCBudW1iZXIgb2YgY29sdW1ucyB3aGVyZSBzb21lb25lIGhhcyBhICIxIgpgYGAKClE6IFdoYXQgaXMgdGhlIGZyZXF1ZW5jeSBvZiBhbGxlbGUyIGZvciByczU1OTI2MDI0IGluIG91ciBzYW1wbGVzPwoKYGBge3J9CnRvdGFsLmFsbGVsZXMgPC0gbi5zYW1wbGVzICogMgojIG11bHRpcGx5IHRpbWVzIDIgc2luY2UgbG9va2luZyBhdCBhIGRpcGxvaWQgKDIgYWxsZWxlIGNvcGllcykKc3VtKGdlbm90eXBlLm1hdHJpeFtzbnAucm93LF0pIC8gdG90YWwuYWxsZWxlcwojIHNpbmNlIGxlc3MgZnJlcXVlbnQgYWxsZWxlLCBzb21ldGltZXMgY2FsbGVkIG1pbm9yIG9yIChtaW5vciBhbGxlbGUgZnJlcXVlbmN5ID0gTUFGICg/KSkKYGBgCgojIyMgR2VuZSBleHByZXNzaW9uIGRhdGEKCldlIHdpbGwgdXNlIFJOQS1zZXEgZ2VuZSBleHByZXNzaW9uIGRhdGEgZnJvbSB0aGUgR0VVVkFESVMgcHJvamVjdC4gVGhlIGRhdGEgYXJlIGZyb20gdGhlIHNhbWUgWW9ydWJhIGNlbGwgbGluZXMgdGhhdCB3ZSBoYXZlIGdlbm90eXBlcyBmb3IuIFRoZSByZWFkcyBoYXZlIGFscmVhZHkgYmVlbiBtYXBwZWQgdG8gdGhlIGdlbm9tZSBhbmQgZ2VuZSBleHByZXNzaW9uIGhhcyBiZWVuIGVzdGltYXRlZCB1c2luZyB0aGUgdHJhbnNjcmlwdHMtcGVyLW1pbGxpb24gKFRQTSkgbWVhc3VyZS4gKEZvciBhbiBleHBsYW5hdGlvbiBvZiBUUE0gc2VlIDxodHRwOi8vd3d3LnJuYS1zZXFibG9nLmNvbS9ycGttLWZwa20tYW5kLXRwbS1jbGVhcmx5LWV4cGxhaW5lZC8+KS4KClJlYWQgaW4gbWFwcGVkIFJOQS1zZXEgcmVhZCBjb3VudHMgZm9yIGVhY2ggZ2VuZS4gVGhlIGZpcnN0IGNvbHVtbnMgNSBnaXZlIGluZm9ybWF0aW9uIGFib3V0IHRoZSBnZW5lLiBUaGUgc3Vic2VxdWVudCBjb2x1bW5zIHRoYXQgc3RhcnQgd2l0aCAiTkEiIChlLmcuIE5BMTg1MjApIGNvbnRhaW4gVFBNIGVzdGltYXRlcyBmb3IgZWFjaCBzYW1wbGUgaW4gdGhlIHN0dWR5LgoKYGBge3J9CiMgVkNGID0gZmlsZSB0aGF0IGdlbmV0b3lpbmcgaW5mbyBpcyBwcm92aWRlZCBpbi4gSGFzIGEgbG90IG9mIGluZm9ybWF0aW9uIGluIGl0CgoKdHBtLmV4cHIudGFiIDwtIHJlYWQudGFibGUoImdlbmVfZXhwcl90cG0udHh0IiwgaGVhZGVyPVQpCmhlYWQodHBtLmV4cHIudGFiKQoKIyBHZW5lIG5hbWUgPSBFTlNHCiMgY2hvbWUgbG9jYXRpb24KIyBjRE5BIExFTl9leHByZXNzaW9uIGVzdGltYXRlcwpgYGAKCiMjIEFuYWx5emUgZ2VuZSBleHByZXNzaW9uIHZhbHVlcwoKUTogSG93IG1hbnkgZ2VuZXMgYXJlIGluIHRoZSBnZW5lIGV4cHJlc3Npb24gdGFibGU/CgpgYGB7cn0KbnJvdyh0cG0uZXhwci50YWIpCiNsZW5ndGgodHBtLmV4cHIudGFiKSBsZW5ndGggaXMgaG93IG1hbnkgdmFyaWFibGUsIHNvIHRoYXQgd291bGQgYmUgY2VsbCBsaW5lIHBsdXMgYSBmZXcgb3RoZXIgY29sdW1ucwojIGh1bWFuIGdlbm9tZSBoYXMgYWJvdXQgMjAsMDAwIHByb3RlaW4gY29kaW5nIGdlbmVzLCBidXQgdGhpcyBmaWxlIGhhcyBjb2RpbmcgYW5kIG5vbi1wcm90ZWluIGNvZGluZyBnZW5lcyAoZGlmZmVyZW50IHRweWVzIG9mIFJOQXMgbGlrZSBsb25nIG5vbi1jb2RpbmcgUk5BcykKIyB0aGlzIGlzIG5vdCBhcyBpZGVhbCBzaW5jZSB3ZSBtb3N0bHkganVzdCBjYXJlIGFib3V0IGNvZGluZwpgYGAKClRoaXMgaXMgYSBsb3Qgb2YgJ2dlbmVzJyEgVGhlIEVuc2VtYmwgJ0VOU0cnIGdlbmUgbGlzdCBjb250YWlucyBtYW55IHBzZXVkby1nZW5lcywgYW5kIGxvdy1leHByZXNzaW9uIGxuY1JOQXMgZXRjLgoKQ2FsY3VsYXRlIG1lYW4gZXhwcmVzc2lvbiBhY3Jvc3Mgc2FtcGxlcywgdGhlbiBtYWtlIGEgaGlzdG9ncmFtIG9mIGxvZyBtZWFuIFRQTSB2YWx1ZXMgZm9yIGdlbmVzIHRoYXQgaGF2ZSBtZWFuIFRQTSBcPiAwLjAuCgpgYGB7cn0KIyBzbyBsZXQncyBqdXN0IGdldCB0aGUgb25lcyB0aGF0IGhhdmUgdGhlIGJpZ2dlc3QgZXhwcmVzc2lvbgojIHRha2UgYSBtZWFuIGFjb3JzcyBlYWNoIHJvdyAoZ2VuZSkgZnJvbSB0aGUgZGlmZmVyZW50IGNlbGwgbGluZXMKIyBleHRyYWN0IGp1c3QgdGhlIGV4cHJlc3Npb24gZGF0YToKYWxsLnRwbS5tYXRyaXggPC0gdHBtLmV4cHIudGFiWyxzYW1wbGUubmFtZXNdCgojIGNvbXB1dGUgbWVhbiBleHByZXNzaW9uIGFuZCBwbG9nIGxvZyBtZWFuIFRQTQojIGdlbmUgZXhwcmVzc2lvbiBoYXMgYSBodWdlIHJhbmdlLCBzbyBpZiB5b3Ugd2FudCB0byBsb29rIGF0IHRoYXQgZGlzdHJ1YnV0aW9uLCBiZXR0ZXIgdG8gdXNlIExvZy4gU28gZmlyc3QgZmlsdGVyIG91dCBnZW5lIHdpdGggMCBleHByc3Npb24gKHdlIGRvbid0IGNhcmUgYWJvdXQgdGhvc2UpCm1lYW4uZXhwciA8LSBhcHBseShhbGwudHBtLm1hdHJpeCwgMSwgbWVhbikKZiA8LSBtZWFuLmV4cHIgPiAwLjAKaGlzdChsb2cobWVhbi5leHByW2ZdKSwgYnJlYWtzPTEwMCkKCiMgeCBheGlzID0gbG9nIFRQTQojIHNvIHRoaW5ncyBiZWxvdyAwIGFyZSBwcm9iYWxieSBub3QgZXhwcmVzc2VkCmBgYAoKVGhlIG1lYW4gZXhwcmVzc2lvbiBkaXN0cmlidXRpb24gaXMgYmltb2RhbCwgd2l0aCBhIGxhcmdlIG51bWJlciBvZiBsb3ctZXhwcmVzc2lvbiBnZW5lcy4KClE6IEhvdyBtYW55IGdlbmVzIGhhdmUgbWVhbiBUUE0gdmFsdWVzIFw+IDEuMD8KCmBgYHtyfQojIFRha2UgZ2VuZXMgd2l0aCBleHByZXNzaW9uIHZhbHVlIG9mIFRQTSA+MQpzdW0obWVhbi5leHByID4gMSkKYGBgCgpUaGlzIGlzIGEgcmVhc29uYWJsZSBudW1iZXIgb2YgZ2VuZXMgdG8gY29uc2lkZXIgZXhwcmVzc2VkIGluIHRoaXMgY2VsbCB0eXBlIChseW1waG9ibGFzdG9pZCBjZWxsIGxpbmVzKS4gU28gbGV0cyBkaXNjYXJkIGFsbCBnZW5lcyB3aXRoIFRQTSBcPCAxLjAgZnJvbSBmdXJ0aGVyIGFuYWx5c2VzLgoKYGBge3J9Cm1lYW4uZXhwciA8LSBhcHBseShhbGwudHBtLm1hdHJpeCwgMSwgbWVhbikKZiA8LSBtZWFuLmV4cHIgPiAxCmhpc3QobG9nKG1lYW4uZXhwcltmXSksIGJyZWFrcz0xMDApCmBgYAoKIyMgT3RoZXIgZGF0YSBwcmUtcHJvY2Vzc2luZwoKVGhlcmUgYXJlIGFkZGl0aW9uYWwgc3RlcHMgd2UgY291bGQgdGFrZSB3aGVuIHByb2Nlc3NpbmcgdGhlIGdlbmUgZXhwcmVzc2lvbiBhbmQgZ2Vub3R5cGUgZGF0YS4KCi0gICBDb3JyZWN0IGZvciBwb3B1bGF0aW9uIHN0cnVjdHVyZSBieSBkb2luZyBwcmluY2lwYWwgY29tcG9uZW50cyBhbmFseXNpcyBvZiBnZW5vdHlwZSBtYXRyaXggKFBDcyBjb3VsZCBiZSB1c2VkIGFzIGNvLXZhcmlhdGVzIGluIGxpbmVhciBtb2RlbCkKLSAgIENvcnJlY3QgZm9yIGV4cHJlc3Npb24gYmF0Y2ggZWZmZWN0cyBieSByZWdyZXNzaW5nIG91dCBQQ3MgKHByaW5jaXBsZSBjb21wb25lbnRzKSwgcGVyZm9ybWluZyBxdWFudGlsZSBub3JtYWxpemF0aW9uCgojIyBpZGVudGlmeWluZyBlUVRMcwoKR2V0IGEgc2V0IG9mIGdlbmVzIHRoYXQgYXJlIG9uIGNocjIyIGFuZCB0aGF0IGhhdmUgVFBNIFw+IDEuMAoKYGBge3J9CmYgPC0gKHRwbS5leHByLnRhYiRDSFJPTSA9PSAiY2hyMjIiKSAmIChtZWFuLmV4cHIgPiAxLjApCmNocjIyLnRwbS5leHByLnRhYiA8LSB0cG0uZXhwci50YWJbZixdCmNocjIyLnRwbS5tYXRyaXggPC0gdHBtLmV4cHIudGFiW2Ysc2FtcGxlLm5hbWVzXSAKCmhlYWQoY2hyMjIudHBtLm1hdHJpeCkKIyBub3cgZXZlcnkgY2VsbCBsaW5lIGhhcyBnZW5lcyBld2l0aCBleHByZXNzaW9uIHZhbHVlcwpgYGAKClBsb3QgdGhlIGV4cHJlc3Npb24gb2YgZ2VuZSBFTlNHMDAwMDAyMTg1MzcgKCoqTUlGLUFTMSoqKSBhcyBhIGZ1bmN0aW9uIG9mIHRoZSBnZW5vdHlwZSBvZiB0aGUgKipTTlAgcnM1NzYwMTA4KiouCgpgYGB7cn0KIyBnZW5lIGV4cHJlc3Npb24gZm9yIG9uZSBnZW5lCiMgZ2VuZSBFTlNHLCBTTlAgcnMjIyMKZXhwciA8LSB1bmxpc3QoY2hyMjIudHBtLm1hdHJpeFtjaHIyMi50cG0uZXhwci50YWIkR0VORS5OQU1FID09ICJFTlNHMDAwMDAyMTg1MzciLF0pCmdlbm9zIDwtIHVubGlzdChnZW5vdHlwZS5tYXRyaXhbZ2Vub3R5cGVzLnRhYiRTTlAuSUQgPT0gInJzNTc2MDEwOCIsXSkKCnBsb3Qoaml0dGVyKGdlbm9zKSwgZXhwciwgeGxhYj0iZ2Vub3R5cGUiLCB5bGFiPSJnZW5lIGV4cHJlc3Npb24gKFRQTSkiKQojIGppdHRlciBhZGRzIG5vaXNlIHNvIHlvdSBjYW4gc2VlIG1vcmUgZGV0YWlscyBvZiB5b3VyIHBsb3QgImF2b2lkIG92ZXJwbG90dGluZyIKYGBgCgpGaXQgYSBsaW5lYXIgbW9kZWwsIHVzaW5nIGV4cHJlc3Npb24gYXMgdGhlIHJlc3BvbnNlIGFuZCBnZW5vdHlwZSBhcyB0aGUgcHJlZGljdG9yCgpgYGB7cn0KIyBsbSA9IGxpbmVhciBtb2RlbAojIH4gaXMgbGlrZSBhbiA9IGZvciB0aGUgbG0gZm9ybXVsYS4gCiMgcHJlZGljdG9yID0gZ2Vub3MuIGNhbiBhZGQgY292YWlhbnRzICgrIHNleCArICBibGFoIGJsYWgpCm1kbCA8LSBsbShleHByIH4gZ2Vub3MpCnN1bW1hcnkobWRsKQoKIyByIHNxdWFyZWQ6IH5leHBsYWluZWQgNDglIG9mIGdlbmV0b3lwZSB3aXRoIFNOUCB2YXJpYXRpb24KIyBjb2VmZmljaWVudCB0YWJlbCBzaG93cyBzaWduaWZpY2FudAojIGxpbmVhciBtb2RlbCBjb2VmZmVpY2VudHMuIE1ha2UgYSBmb3JtdWxhIHRvIGV4bHBhaW4gWSA9IEJldGEwICsgbXggKyBtMngyICsgLi4uLgojIG0gYWxzbyBjYWxsZWQgYmV0YSwgb3IgY29lZmZpZWNudHMuIAojIEJldGEwIGlzIGludGVyY2VwdCAoaW4gdGhpcyBjYXNlIDAuMTkpCiMgZ2Vub3R5cGUgY29lZmZpY2VudCBpcyAxLjFlLTggaXMgcCB2YWx1ZSBmb3IgYXNzb2NhaXRpb24KCgoKYGBgCgpHZXQgdGhlIHNsb3BlIChvZnRlbiBjYWxsZWQgZWZmZWN0IHNpemUgb3IgQmV0YSkgYW5kIHAtdmFsdWUgZnJvbSB0aGUgcmVncmVzc2lvbiwgYW5kIGFkZCB0aGUgZml0IGxpbmUgdG8gdGhlIGdlbm90eXBlIHZzLiBleHByZXNzaW9uIHBsb3QuCgpgYGB7cn0KIyB1c2UgdGhvc2UgaW5mbyB0byBwbG90IHRoZSBhYi1saW5lCmludGVyY2VwdCA8LSBtZGwkY29lZmZpY2llbnRzWzFdCmJldGEgPC0gbWRsJGNvZWZmaWNpZW50c1syXQpzIDwtIHN1bW1hcnkobWRsKQpwLnZhbCA8LSBzJGNvZWZmaWNpZW50c1siZ2Vub3MiLCJQcig+fHR8KSJdCgpwbG90KGppdHRlcihnZW5vcyksIGV4cHIsIHhsYWI9Imdlbm90eXBlIiwgeWxhYj0iZ2VuZSBleHByZXNzaW9uIChUUE0pIikKYWJsaW5lKGE9aW50ZXJjZXB0LCBiPWJldGEsIGNvbD0icmVkIikKCiMgQmV0YTAgPSBpbnRlcmNlcHQgPSB3aGVyZSB0aGUgc3RyaWFnaHQgbGluZSBjcm9zc2VzIDAgLT4gd2hpY2ggaXMgd2hlbiBwZW9wbGUgYXJlIGhvbW96eWdvdXMgZm9yIHJlZmVyZW5jZSBhbGxlbGUKIyBzbG9wZSBvciBiZXRhIGNvZWZmaWNlaW50cyB3b3VsZCBiZSBjaGFuZ2UgaW4gZ2VuZSBleHByZXNzaW9uIC8gZ2Vub3R5cGUgOyBzbG9wZSBiZWluZyAxIHVuaXQgY2hhbmdlIHNvIHdvdWxkIGJlIGRpZmZlcmVudCBpbiBob21venlnb3VzIHRvIGhldGVyb2N5Z291cywgdGhlbiB0byBob21vIGZvciBub24tcmVmZXJlbmNlIGdlbmVvbWVzCiMgcyBvIGl0IGdvZXMgdXAgYnkgMS4yNSBlYWNoIHRpbWUgLCB3aGl1Y2ggaXMgb3VyIGdlbm9zIGNvZWZmaWNlbnQgZXN0aW1hdGUKCiMgc28gdGhpcyBpcyBhbiBlUVRMLCBidXQgdGhpcyB3YXMgY3VycmF0ZWQgZm9yIHVzCmBgYAoKTm93IGxldHMgdGVzdCBhbGwgU05QcyB0aGF0IGFyZSBjbG9zZSAod2l0aGluIDUwa2IpIG9mIHRoZSBnZW5lIEVOU0cwMDAwMDIxODUzNyBmb3IgYXNzb2NpYXRpb24uCgpGaXJzdCBnZXQgdGhlIGdlbm90eXBlcyBvZiBhbGwgb2YgdGhlIG5lYXJieSBTTlBzLgoKbGFyZ2VyIHdpbmRvd3MgYmV0dGVyIGZvciBsYXJnZXIgc2FtcGxlIHNpemVzCgpXaHkgZG8gd2UgdGVzdCBTTlBzIG9ubHkgYXJvdW5kIHRoZSBnZW5lLCBhbmQgbm90IHRocm91Z2hvdXQgdGhlIHdob2xlIGdlbm9tZT8KCldlIHdhbnQgdG8gZW5yaWNoIGZvciBuZWFyIHRoZSBnZW5lIGJlY2F1c2UgdGhhdCdzIHdoZXJlIHRoZSByZWd1bGF0b3J5IGVsZW1lbnRzIGFyZQoKV2hvbGUgZ2Vub21lIHdvdWxkIGJlIG5pY2UsIGJ1dCB0aGF0IGlzIHZlcnkgY2hhbGxlbmdpbmcuIHNvbWUgcGVvcGxlIGRvIGl04oCTIGFuZCB0aGV5IGZpbmQgdHJhbnMtYWN0aW5nIGVRVExzCgotICAgY2lzLWFjdGluZyBlUVRMczogb25seSBhY3Qgb24gdGhlIHNhbWUgYWxsZWxlL2Nob21vc290bWUKCjwhLS0gLS0+CgotICAgVHJhbnMtYWN0aW5nIGVRVExzOiB3aWxsIGFjdCBvbiBzYW1lIGNocm9tbyBhbmQgYW5vdGhlciBjaHJvbW9zb21lCgotICAgTW9zdCB2YXJpYXRpb24gYW5kIGV4cHJlc3Npb24gb2YgZ2VuZXMgaXMgcHJvYmFibHkgdHJhbnMKCmBgYHtyfQojIGNpcy1hbGxlbGVzIHdpdGhpbiA1MGtiIG9mIHRoZSBnZW5lIHRvIGlkZW50aWZ5IHJlZ3VsYXRvcnkgZWxlbWVudHMgdG8gdGVzdCBhbGwgdGhlIFNOUHMgdGhhdCBhcmUgLTUwIGFuZCArNTBrYiBvZiB0aGUgZ2VuZQpnZW5lLnJvdyA8LSB3aGljaChjaHIyMi50cG0uZXhwci50YWIkR0VORS5OQU1FID09ICJFTlNHMDAwMDAyMTg1MzciKQpzdGFydCA8LSBjaHIyMi50cG0uZXhwci50YWIkR0VORS5TVEFSVFtnZW5lLnJvd10gLSA1MDAwMAplbmQgPC0gY2hyMjIudHBtLmV4cHIudGFiJEdFTkUuRU5EW2dlbmUucm93XSArIDUwMDAwCgpzbnAucm93cyA8LSB3aGljaChnZW5vdHlwZXMudGFiJENIUk9NLlBPUyA+PSBzdGFydCAmIGdlbm90eXBlcy50YWIkQ0hST00uUE9TIDw9IGVuZCkKCmdlbm90eXBlcyA8LSBnZW5vdHlwZS5tYXRyaXhbc25wLnJvd3MsXQpuLnNucHMgPC0gbnJvdyhnZW5vdHlwZXMpCgpuLnNucHMKIyB0aGVyZSBhcmUgMTA4MSBnZW5lcyBuZWFyIG91ciBnZW5lIG9mIGludGVyZXN0ICgiNTM3IikKYGBgCgpOZXh0IHBlcmZvcm0gbGluZWFyIHJlZ3Jlc3Npb24gb2YgdGhlIGdlbm95cGVzIG9mIGVhY2ggU05QIGFnYWluc3QgdGhlIGV4cHJlc3Npb24gb2YgdGhlIGdlbmUgYW5kIG1ha2UgYSBoaXN0b2dyYW0gb2YgdGhlIHAtdmFsdWVzLgoKYGBge3J9CnAudmFscyA8LSByZXAoTkEsIG4uc25wcykKCmZvcihpIGluIHNlcSgxLCBuLnNucHMpKSB7CiAgZ2Vub3MgPC0gdW5saXN0KGdlbm90eXBlc1tpLF0pCiAgbWRsIDwtIGxtKGV4cHIgfiBnZW5vcykKICBzIDwtIHN1bW1hcnkobWRsKQogIHAudmFsc1tpXSA8LSBzJGNvZWZmaWNpZW50c1siZ2Vub3MiLCJQcig+fHR8KSJdCn0KCmhpc3QocC52YWxzKQojIHVuZGVyIHRoZSBudWxsLCBoaXNvZ3JhbXMgc2hvdWxkIGJlIHVuaWZvcm0uIHRoaXMgb25lIGlzbid0LCB0aGVyZSBpcyBleGNlc3Mgb2YgbG93IFAgdmFsdWVzLiBXaHkgYXJlIHRoZXJlIHNvIG1hbnkgc2lnbmlmaWNhbnQgU05Qcz8KIyBiZWNhc3VlIHdlIGFyZSBsb29raW5nIGNsb3NlciB0b3QgaGUgZ2VuZSwgYW5kIHdlIGFscmVhZHkga25vdyB0aGVyZSBpcyBhbiBlUVRMLi4gYmVjYXVzZSBvZiBMRCAobGlua2FnZSBkaXNlcXVpbGliaXJ1bSkKYGBgCgpQbG90IHRoZSBnZW5vbWljIHBvc2l0aW9uIG9mIHRoZSBTTlBzICh4LWF4aXMpIGFnYWluc3QgdGhlaXIgLWxvZzEwIHAtdmFsdWVzICh5LWF4aXMpCgpgYGB7cn0KcG9zIDwtIGdlbm90eXBlcy50YWIkQ0hST00uUE9TW3NucC5yb3dzXQpwbG90KHBvcywgLWxvZzEwKHAudmFscyksIHlsYWI9Ii1sb2cxMChwLXZhbHVlKSIsIHhsYWI9ImNocjIyIHBvc2l0aW9uIikKIyBhZGQgdGhlIHBvc2l0aW9uIG9mIHRoZSBnZW5lCmxpbmVzKHg9YyhjaHIyMi50cG0uZXhwci50YWIkR0VORS5TVEFSVFtnZW5lLnJvd10sIGNocjIyLnRwbS5leHByLnRhYiRHRU5FLkVORFtnZW5lLnJvd10pLCB5PWMoMCwwKSwgCiAgICAgICAgIGNvbD0iYmx1ZSIsIGx3ZD00KQojIHNob3dpbmcgMTgwMX4gU05QUyBpbiB0aGUgcmVnaW9uLiBibHVlIGlzIHRoZSBnZW5lLCBhbmQgKy8tNTAga2IgYXJvdW5kIGl0LiBUaGUgc2lnbmZpaWNhbm50IFNOUHMgYXJlIHRvIHRoZSByaWdodCAod2UgZG9uJ3QgcmVtZW1iZXIgaWYgdXAgb3IgZG93bnN0cmVhbSkgb2YgdGhlIGdlbmUKIyBMaWtlbHksIGNhdXNhbCBnZW5lcyBhcmUgdGhlIHR3byB1cHBlciByaWdodApgYGAK