1 Estimates!

## The scale difference between the smallest and largest
## libraries is > 10. Assuming a log10 scale is better, set scale=FALSE if not.

## This function will replace the expt$expressionset slot with:
## log2(cpm(quant(simple(data))))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Not correcting the count-data for batch effects.  If batch is
##  included in EdgerR/limma's model, then this is probably wise; but in extreme
##  batch effects this is a good parameter to play with.
## Step 1: performing count filter with option: simple
## Removing 212 low-count genes (19417 remaining).
## Step 2: normalizing the data with quant.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 6752 values equal to 0, adding 1 to the matrix.
## Step 5: not doing batch correction.

## plot labels was not set and there are more than 100 samples, disabling it.
## Not putting labels on the plot.

## This function will replace the expt$expressionset slot with:
## log2(svaseq(cpm(quant(simple(data)))))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Warning in normalize_expt(hs_expt, transform = "log2", convert = "cpm", :
## Quantile normalization and sva do not always play well together.
## Step 1: performing count filter with option: simple
## Removing 212 low-count genes (19417 remaining).
## Step 2: normalizing the data with quant.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 6752 values equal to 0, adding 1 to the matrix.
## Step 5: doing batch correction with svaseq.
## Note to self:  If you get an error like 'x contains missing values' The data has too many 0's and needs a stronger low-count filter applied.
## Passing off to all_adjusters.
## batch_counts: Before batch/surrogate estimation, 1022588 entries are x>1: 51.6%.
## batch_counts: Before batch/surrogate estimation, 6752 entries are x==0: 0.341%.
## batch_counts: Before batch/surrogate estimation, 951194 entries are 0<x<1: 48.0%.
## The be method chose 10 surrogate variable(s).
## Attempting svaseq estimation with 10 surrogates.
## There are 30781 (1.55%) elements which are < 0 after batch correction.
## plot labels was not set and there are more than 100 samples, disabling it.
## Not putting labels on the plot.

## This function will replace the expt$expressionset slot with:
## log2(svaseq(quant(simple(data))))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Leaving the data unconverted.  It is often advisable to cpm/rpkm
##  the data to normalize for sampling differences, keep in mind though that rpkm
##  has some annoying biases, and voom() by default does a cpm (though hpgl_voom()
##  will try to detect this).
## Warning in normalize_expt(hs_expt, transform = "log2", norm = "quant",
## filter = "simple", : Quantile normalization and sva do not always play well
## together.
## Step 1: performing count filter with option: simple
## Removing 212 low-count genes (19417 remaining).
## Step 2: normalizing the data with quant.
## Step 3: not converting the data.
## Step 4: transforming the data with log2.
## transform_counts: Found 6752 values equal to 0, adding 1 to the matrix.
## Step 5: doing batch correction with svaseq.
## Note to self:  If you get an error like 'x contains missing values' The data has too many 0's and needs a stronger low-count filter applied.
## Passing off to all_adjusters.
## batch_counts: Before batch/surrogate estimation, 1473620 entries are x>1: 74.4%.
## batch_counts: Before batch/surrogate estimation, 6752 entries are x==0: 0.341%.
## batch_counts: Before batch/surrogate estimation, 500162 entries are 0<x<1: 25.3%.
## The be method chose 11 surrogate variable(s).
## Attempting svaseq estimation with 11 surrogates.
## There are 4732 (0.239%) elements which are < 0 after batch correction.
## plot labels was not set and there are more than 100 samples, disabling it.
## Not putting labels on the plot.

2 Add our data

Najib asked about adding the various data provided by our work. The expressionset which contains this information live in ‘../multiple_leishmania_2018’, more explicitly, the expressionset may be loaded via Hs_M0Lm4h.rda

## This function will replace the expt$expressionset slot with:
## log2(cpm(quant(cbcb(data))))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Not correcting the count-data for batch effects.  If batch is
##  included in EdgerR/limma's model, then this is probably wise; but in extreme
##  batch effects this is a good parameter to play with.
## Step 1: performing count filter with option: cbcb
## Removing 0 low-count genes (19629 remaining).
## Step 2: normalizing the data with quant.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 9876 values equal to 0, adding 1 to the matrix.
## Step 5: not doing batch correction.
## plot labels was not set and there are more than 100 samples, disabling it.
## Not putting labels on the plot.
## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure

## Warning in MASS::cov.trob(data[, vars]): Probable convergence failure

## This function will replace the expt$expressionset slot with:
## log2(svaseq(cpm(quant(cbcb(data)))))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Warning in normalize_expt(all_expt, filter = TRUE, norm = "quant", convert
## = "cpm", : Quantile normalization and sva do not always play well together.
## Step 1: performing count filter with option: cbcb
## Removing 0 low-count genes (19629 remaining).
## Step 2: normalizing the data with quant.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 9876 values equal to 0, adding 1 to the matrix.
## Step 5: doing batch correction with svaseq.
## Note to self:  If you get an error like 'x contains missing values' The data has too many 0's and needs a stronger low-count filter applied.
## Passing off to all_adjusters.
## batch_counts: Before batch/surrogate estimation, 4233025 entries are x>1: 58.4%.
## batch_counts: Before batch/surrogate estimation, 9876 entries are x==0: 0.136%.
## batch_counts: Before batch/surrogate estimation, 3000200 entries are 0<x<1: 41.4%.
## The be method chose 25 surrogate variable(s).
## Attempting svaseq estimation with 25 surrogates.
## There are 211468 (2.92%) elements which are < 0 after batch correction.
## plot labels was not set and there are more than 100 samples, disabling it.
## Not putting labels on the plot.

3 Break apart the expt

Najib wants to set the colors/sizes/shapes for the set of all samples, including our data from previous work . In order to do that, I am going to need to break apart the expt into its component pieces, edit the experimental design in order to match it with his query, and recreate the expressionset.

So, lets do it.

I edited the metadata sheet, filling in numeric values for time, (partially) standardizing the host cell types, and filling in the infection state. Oh! But I think a bunch of the ones which currently say uninfected are actually stimulated! Lets go back through and check that before moving forward.

## Reading the sample metadata.
## The sample definitions comprises: 369 rows(samples) and 61 columns(metadata fields).
## Matched 19629 annotations and counts.
## Bringing together the count matrix and gene information.
## The final expressionset has 19629 rows and 369 columns.

3.1 Play with the re-created expressionset.

## There were 369, now there are 296 samples.
## There were 296, now there are 271 samples.
## This function will replace the expt$expressionset slot with:
## log2(svaseq(cpm(quant(cbcb(data)))))
## It will save copies of each step along the way
##  in expt$normalized with the corresponding libsizes. Keep libsizes in mind
##  when invoking limma.  The appropriate libsize is non-log(cpm(normalized)).
##  This is most likely kept at:
##  'new_expt$normalized$intermediate_counts$normalization$libsizes'
##  A copy of this may also be found at:
##  new_expt$best_libsize
## Warning in normalize_expt(newer_expt, filter = "cbcb", convert = "cpm", :
## Quantile normalization and sva do not always play well together.
## Step 1: performing count filter with option: cbcb
## Removing 0 low-count genes (19629 remaining).
## Step 2: normalizing the data with quant.
## Step 3: converting the data with cpm.
## Step 4: transforming the data with log2.
## transform_counts: Found 6269 values equal to 0, adding 1 to the matrix.
## Step 5: doing batch correction with svaseq.
## Note to self:  If you get an error like 'x contains missing values' The data has too many 0's and needs a stronger low-count filter applied.
## Passing off to all_adjusters.
## batch_counts: Before batch/surrogate estimation, 2925747 entries are x>1: 55.0%.
## batch_counts: Before batch/surrogate estimation, 6269 entries are x==0: 0.118%.
## batch_counts: Before batch/surrogate estimation, 2387443 entries are 0<x<1: 44.9%.
## The be method chose 45 surrogate variable(s).
## Attempting svaseq estimation with 45 surrogates.
## There are 180019 (3.38%) elements which are < 0 after batch correction.
## plot labels was not set and there are more than 100 samples, disabling it.
## Not putting labels on the plot.

LS0tCnRpdGxlOiAiRG93bmxvYWRlZCBkYXRhIHNldHMsIHNhbXBsZSBlc3RpbWF0aW9uLiIKYXV0aG9yOiAiYXRiIGFiZWxld0BnbWFpbC5jb20iCmRhdGU6ICJgciBTeXMuRGF0ZSgpYCIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGZpZ19jYXB0aW9uOiB0cnVlCiAgICBmaWdfaGVpZ2h0OiA3CiAgICBmaWdfd2lkdGg6IDcKICAgIGhpZ2hsaWdodDogdGFuZ28KICAgIGtlZXBfbWQ6IGZhbHNlCiAgICBtb2RlOiBzZWxmY29udGFpbmVkCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKICAgIHNlbGZfY29udGFpbmVkOiB0cnVlCiAgICB0aGVtZTogcmVhZGFibGUKICAgIHRvYzogdHJ1ZQogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCiAgcm1kZm9ybWF0czo6cmVhZHRoZWRvd246CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBjb2RlX2ZvbGRpbmc6IHNob3cKICAgIGRmX3ByaW50OiBwYWdlZAogICAgZmlnX2NhcHRpb246IHRydWUKICAgIGZpZ19oZWlnaHQ6IDcKICAgIGZpZ193aWR0aDogNwogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAgd2lkdGg6IDMwMAogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIHRvY19mbG9hdDogdHJ1ZQogIEJpb2NTdHlsZTo6aHRtbF9kb2N1bWVudDoKICAgIGNvZGVfZG93bmxvYWQ6IHRydWUKICAgIGNvZGVfZm9sZGluZzogc2hvdwogICAgZmlnX2NhcHRpb246IHRydWUKICAgIGZpZ19oZWlnaHQ6IDcKICAgIGZpZ193aWR0aDogNwogICAgaGlnaGxpZ2h0OiB0YW5nbwogICAga2VlcF9tZDogZmFsc2UKICAgIG1vZGU6IHNlbGZjb250YWluZWQKICAgIHRvY19mbG9hdDogdHJ1ZQotLS0KCjxzdHlsZSB0eXBlPSJ0ZXh0L2NzcyI+CmJvZHksIHRkIHsKICBmb250LXNpemU6IDE2cHg7Cn0KY29kZS5yewogIGZvbnQtc2l6ZTogMTZweDsKfQpwcmUgewogZm9udC1zaXplOiAxNnB4Cn0KPC9zdHlsZT4KCmBgYHtyIG9wdGlvbnMsIGluY2x1ZGU9RkFMU0V9CmxpYnJhcnkoImhwZ2x0b29scyIpCnR0IDwtIGRldnRvb2xzOjpsb2FkX2FsbCgiL2RhdGEvaHBnbHRvb2xzIikKa25pdHI6Om9wdHNfa25pdCRzZXQod2lkdGg9MTIwLAogICAgICAgICAgICAgICAgICAgICBwcm9ncmVzcz1UUlVFLAogICAgICAgICAgICAgICAgICAgICB2ZXJib3NlPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgIGVjaG89VFJVRSkKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVycm9yPVRSVUUsCiAgICAgICAgICAgICAgICAgICAgICBkcGk9OTYpCm9sZF9vcHRpb25zIDwtIG9wdGlvbnMoZGlnaXRzPTQsCiAgICAgICAgICAgICAgICAgICAgICAgc3RyaW5nc0FzRmFjdG9ycz1GQUxTRSwKICAgICAgICAgICAgICAgICAgICAgICBrbml0ci5kdXBsaWNhdGUubGFiZWw9ImFsbG93IikKZ2dwbG90Mjo6dGhlbWVfc2V0KGdncGxvdDI6OnRoZW1lX2J3KGJhc2Vfc2l6ZT0xMCkpCnJ1bmRhdGUgPC0gZm9ybWF0KFN5cy5EYXRlKCksIGZvcm1hdD0iJVklbSVkIikKCnZlciA8LSAiMjAxOTA3MDEiCnByZXZpb3VzX2ZpbGUgPC0gcGFzdGUwKCIwMV9hbm5vdGF0aW9uXyIsIHZlciwgIi5SbWQiKQoKdG1wIDwtIHNtKGxvYWRtZShmaWxlbmFtZT1wYXN0ZTAoZ3N1YihwYXR0ZXJuPSJcXC5SbWQiLCByZXBsYWNlPSIiLCB4PXByZXZpb3VzX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikpKQpybWRfZmlsZSA8LSAiMDJfZXN0aW1hdGlvbl8yMDE5MDcwMS5SbWQiCmBgYAoKIyBFc3RpbWF0ZXMhCgpgYGB7ciBlc3RpbWF0ZX0KaHNfZXhwdCA8LSBzZXRfZXhwdF9jb25kaXRpb25zKGhzX2V4cHQsIGZhY3Q9ImluZmVjdHN0YXRlIikKaHNfZXhwdCA8LSBzZXRfZXhwdF9iYXRjaGVzKGhzX2V4cHQsIGZhY3Q9InN0dWR5cG1pZCIpCgpwbG90X2xpYnNpemUoaHNfZXhwdCkkcGxvdApoc19ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGhzX2V4cHQsIHRyYW5zZm9ybT0ibG9nMiIsIGNvbnZlcnQ9ImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybT0icXVhbnQiLCBmaWx0ZXI9InNpbXBsZSIpCmhzX2NvciA8LSBwbG90X2NvcmhlYXQoaHNfbm9ybSkKaHNfcGNhIDwtIHBsb3RfcGNhKGhzX25vcm0pCmhzX3BjYSRwbG90Cgpoc19uYiA8LSBub3JtYWxpemVfZXhwdChoc19leHB0LCB0cmFuc2Zvcm09ImxvZzIiLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgIG5vcm09InF1YW50IiwgZmlsdGVyPSJzaW1wbGUiLCBiYXRjaD0ic3Zhc2VxIikKCmhzX25iX3BjYSA8LSBwbG90X3BjYShoc19uYikKaHNfbmJfcGNhJHBsb3QKCmhzX2V4cHQgPC0gc2V0X2V4cHRfY29uZGl0aW9ucyhoc19leHB0LCBmYWN0PSJleHB0dGltZSIpCgpoc19ub3JtIDwtIG5vcm1hbGl6ZV9leHB0KGhzX2V4cHQsIHRyYW5zZm9ybT0ibG9nMiIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgbm9ybT0icXVhbnQiLCBmaWx0ZXI9InNpbXBsZSIsIGJhdGNoPSJzdmFzZXEiKQpoc19wY2EgPC0gcGxvdF9wY2EoaHNfbm9ybSkKaHNfcGNhJHBsb3QKYGBgCgojIEFkZCBvdXIgZGF0YQoKTmFqaWIgYXNrZWQgYWJvdXQgYWRkaW5nIHRoZSB2YXJpb3VzIGRhdGEgcHJvdmlkZWQgYnkgb3VyIHdvcmsuICBUaGUKZXhwcmVzc2lvbnNldCB3aGljaCBjb250YWlucyB0aGlzIGluZm9ybWF0aW9uIGxpdmUgaW4KJy4uL211bHRpcGxlX2xlaXNobWFuaWFfMjAxOCcsIG1vcmUgZXhwbGljaXRseSwgdGhlIGV4cHJlc3Npb25zZXQgbWF5IGJlIGxvYWRlZAp2aWEgSHNfTTBMbTRoLnJkYQoKYGBge3IgYWRkX291cl9kYXRhfQpsb2FkKCIuLi9tdWx0aXBsZV9sZWlzaG1hbmlhXzIwMTgvSHNfTTBMbTRoLnJkYSIpCgphbGxfZXhwdCA8LSBjb21iaW5lX2V4cHRzKGhzX2V4cHQsIGV4cHQsIG1lcmdlX21ldGE9VFJVRSkKCmFsbF9leHB0IDwtIHNldF9leHB0X2NvbmRpdGlvbnMoYWxsX2V4cHQsIGZhY3Q9ImluZmVjdHN0YXRlIikKYWxsX24gPC0gbm9ybWFsaXplX2V4cHQoYWxsX2V4cHQsIGZpbHRlcj1UUlVFLCBub3JtPSJxdWFudCIsIGNvbnZlcnQ9ImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybT0ibG9nMiIpCgojI3Rlc3RfcGNhIDwtIHBjYV9pbmZvcm1hdGlvbihhbGxfZXhwdCwgbnVtX3Bjcz00LCBwbG90X3BjYXM9VFJVRSwKIyMgICAgICAgICAgICAgICAgICAgICAgICAgICAgZXhwdF9mYWN0b3JzPWMoImNvbmRpdGlvbiIsICJiYXRjaCIsICJob3N0Y2VsbHNvdXJjZSIsCiMjICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJwYXRob2dlbnNwZWNpZXMiLCAiZXhwdHRpbWUiKSkKCnBsb3RfcGNhKGFsbF9uKSRwbG90CgphbGxfbmIgPC0gbm9ybWFsaXplX2V4cHQoYWxsX2V4cHQsIGZpbHRlcj1UUlVFLCBub3JtPSJxdWFudCIsIGNvbnZlcnQ9ImNwbSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybT0ibG9nMiIsIGJhdGNoPSJzdmFzZXEiKQphbGxfcGNhIDwtIHBsb3RfcGNhKGFsbF9uYikKYWxsX3BjYSRwbG90CmBgYAoKIyBCcmVhayBhcGFydCB0aGUgZXhwdAoKTmFqaWIgd2FudHMgdG8gc2V0IHRoZSBjb2xvcnMvc2l6ZXMvc2hhcGVzIGZvciB0aGUgc2V0IG9mIGFsbCBzYW1wbGVzLCBpbmNsdWRpbmcKb3VyIGRhdGEgZnJvbSBwcmV2aW91cyB3b3JrIC4gIEluIG9yZGVyIHRvIGRvIHRoYXQsIEkgYW0gZ29pbmcgdG8gbmVlZCB0byBicmVhawphcGFydCB0aGUgZXhwdCBpbnRvIGl0cyBjb21wb25lbnQgcGllY2VzLCBlZGl0IHRoZSBleHBlcmltZW50YWwgZGVzaWduIGluIG9yZGVyCnRvIG1hdGNoIGl0IHdpdGggaGlzIHF1ZXJ5LCBhbmQgcmVjcmVhdGUgdGhlIGV4cHJlc3Npb25zZXQuCgpTbywgbGV0cyBkbyBpdC4KCmBgYHtyIGJyZWFrX2V4cHRfc2V0dXB9CiMjIFRoaXMgc2hvdWxkIHJlYWxseSBvbmx5IGJlIHJ1biBtYW51YWxseSwgYmVjYXVzZSBJIHdpbGwgYmUgdXNpbmcgdGhpcwojIyB0byByZWNyZWF0ZSB0aGUgZnVsbCBzZXQgb2YgZXhwZXJpbWVudGFsIGRlc2lnbiBhY3Jvc3MgbXVsdGlwbGUgcmV2aXNpb25zIG9mCiMjIG15IG1ldGFkYXRhLgp2ZXJzaW9uX2lkIDwtICIyMDE5MDciCmNvdW50X3NoZWV0IDwtIGdsdWU6OmdsdWUoInNhbXBsZV9zaGVldHMvYWxsX2NvdW50c197dmVyc2lvbl9pZH0ueGxzeCIpCmFsbF9jb3VudHMgPC0gYXMuZGF0YS5mcmFtZShleHBycyhhbGxfZXhwdCkpCmFubm90X3NoZWV0IDwtIGdsdWU6OmdsdWUoInNhbXBsZV9zaGVldHMvYWxsX2Fubm90X3t2ZXJzaW9uX2lkfS54bHN4IikKYWxsX2Fubm90IDwtIGFzLmRhdGEuZnJhbWUoZkRhdGEoYWxsX2V4cHQpKQptZXRhX3NoZWV0IDwtIGdsdWU6OmdsdWUoInNhbXBsZV9zaGVldHMvYWxsX21ldGFfe3ZlcnNpb25faWR9Lnhsc3giKQphbGxfbWV0YSA8LSBhcy5kYXRhLmZyYW1lKHBEYXRhKGFsbF9leHB0KSkKYGBgCgpgYGB7ciBicmVha19leHB0LCBldmFsPUZBTFNFfQp0dCA8LSB3cml0ZV94bHMoZGF0YT1hbGxfbWV0YSwgZXhjZWw9bWV0YV9zaGVldCkKdHQgPC0gd3JpdGVfeGxzKGRhdGE9YWxsX2Fubm90LCBleGNlbD1hbm5vdF9zaGVldCkKdHQgPC0gd3JpdGVfeGxzKGRhdGE9YWxsX2NvdW50cywgZXhjZWw9Y291bnRfc2hlZXQpCmBgYAoKSSBlZGl0ZWQgdGhlIG1ldGFkYXRhIHNoZWV0LCBmaWxsaW5nIGluIG51bWVyaWMgdmFsdWVzIGZvciB0aW1lLCAocGFydGlhbGx5KQpzdGFuZGFyZGl6aW5nIHRoZSBob3N0IGNlbGwgdHlwZXMsIGFuZCBmaWxsaW5nIGluIHRoZSBpbmZlY3Rpb24gc3RhdGUuICBPaCEgIEJ1dApJIHRoaW5rIGEgYnVuY2ggb2YgdGhlIG9uZXMgd2hpY2ggY3VycmVudGx5IHNheSB1bmluZmVjdGVkIGFyZSBhY3R1YWxseQpzdGltdWxhdGVkISBMZXRzIGdvIGJhY2sgdGhyb3VnaCBhbmQgY2hlY2sgdGhhdCBiZWZvcmUgbW92aW5nIGZvcndhcmQuCgpgYGB7ciByZXBsb3R9Cm5ld19jb3VudHMgPC0gb3Blbnhsc3g6OnJlYWRXb3JrYm9vayh4bHN4RmlsZT1jb3VudF9zaGVldCkKcm93bmFtZXMobmV3X2NvdW50cykgPC0gbmV3X2NvdW50c1tbInJvdy5uYW1lcyJdXQpuZXdfY291bnRzW1sicm93Lm5hbWVzIl1dIDwtIE5VTEwKY29sbmFtZXMobmV3X2NvdW50cykgPC0gZ3N1YihwYXR0ZXJuPSJeKC4qKV8uKiQiLCByZXBsYWNlbWVudD0iXFwxIiwgeD1jb2xuYW1lcyhuZXdfY291bnRzKSkKbmV3X21ldGEgPC0gb3Blbnhsc3g6OnJlYWRXb3JrYm9vayh4bHN4RmlsZT1tZXRhX3NoZWV0KQpyb3duYW1lcyhuZXdfbWV0YSkgPC0gbmV3X21ldGFbWyJyb3cubmFtZXMiXV0KbmV3X21ldGFbWyJyb3cubmFtZXMiXV0gPC0gTlVMTApjb2xuYW1lcyhuZXdfbWV0YSkgPC0gZ3N1YihwYXR0ZXJuPSJeKC4qKV8uKiQiLCByZXBsYWNlbWVudD0iXFwxIiwgeD1jb2xuYW1lcyhuZXdfbWV0YSkpCm5ld19hbm5vdCA8LSBvcGVueGxzeDo6cmVhZFdvcmtib29rKHhsc3hGaWxlPWFubm90X3NoZWV0KQpyb3duYW1lcyhuZXdfYW5ub3QpIDwtIG5ld19hbm5vdFtbInJvdy5uYW1lcyJdXQpuZXdfYW5ub3RbWyJyb3cubmFtZXMiXV0gPC0gTlVMTApjb2xuYW1lcyhuZXdfYW5ub3QpIDwtIGdzdWIocGF0dGVybj0iXiguKilfLiokIiwgcmVwbGFjZW1lbnQ9IlxcMSIsIHg9Y29sbmFtZXMobmV3X2Fubm90KSkKCm5ld19leHB0IDwtIGNyZWF0ZV9leHB0KG1ldGFkYXRhPW5ld19tZXRhLAogICAgICAgICAgICAgICAgICAgICAgICBjb3VudF9kYXRhZnJhbWU9bmV3X2NvdW50cywKICAgICAgICAgICAgICAgICAgICAgICAgZ2VuZV9pbmZvPW5ld19hbm5vdCkKYGBgCgojIyBQbGF5IHdpdGggdGhlIHJlLWNyZWF0ZWQgZXhwcmVzc2lvbnNldC4KCmBgYHtyIHBsYXl9Cm5ld2VyX2V4cHQgPC0gc3Vic2V0X2V4cHQobmV3X2V4cHQsIHN1YnNldD0idGltZWhvdXJzIT0ndW5kZWYnIikKbmV3ZXJfZXhwdCA8LSBzdWJzZXRfZXhwdChuZXdlcl9leHB0LCBzdWJzZXQ9Imhvc3RjZWxsc291cmNlIT0nc2tpbiciKQpuZXdlcl9leHB0IDwtIHNldF9leHB0X2NvbmRpdGlvbnMobmV3ZXJfZXhwdCwgZmFjdD0icGF0aG9nZW5zcGVjaWVzIikKbmV3ZXJfZXhwdCA8LSBzZXRfZXhwdF9iYXRjaGVzKG5ld2VyX2V4cHQsIGZhY3Q9Imhvc3RjZWxsc291cmNlIikKbmV3ZXJfbm9ybSA8LSBub3JtYWxpemVfZXhwdChuZXdlcl9leHB0LCBmaWx0ZXI9ImNiY2IiLCBjb252ZXJ0PSJjcG0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRyYW5zZm9ybT0ibG9nMiIsIG5vcm09InF1YW50IiwgYmF0Y2g9InN2YXNlcSIpCgpuZXdlcl9wYyA8LSBwbG90X3BjYShuZXdlcl9ub3JtLCBzaXplX2NvbHVtbj0idGltZWhvdXJzIiwgc2l6ZV9vcmRlcj1jKDAsNCwyNCw1MCwxMjApKQpuZXdlcl9wYyRwbG90CmBgYAoKYGBge3Igc2F2ZW1lLCBldmFsPUZBTFNFfQpwYW5kZXI6OnBhbmRlcihzZXNzaW9uSW5mbygpKQptZXNzYWdlKHBhc3RlMCgiVGhpcyBpcyBocGdsdG9vbHMgY29tbWl0OiAiLCBnZXRfZ2l0X2NvbW1pdCgpKSkKdGhpc19zYXZlIDwtIHBhc3RlMChnc3ViKHBhdHRlcm49IlxcLlJtZCIsIHJlcGxhY2U9IiIsIHg9cm1kX2ZpbGUpLCAiLXYiLCB2ZXIsICIucmRhLnh6IikKbWVzc2FnZShwYXN0ZTAoIlNhdmluZyB0byAiLCB0aGlzX3NhdmUpKQp0bXAgPC0gc20oc2F2ZW1lKGZpbGVuYW1lPXRoaXNfc2F2ZSkpCmBgYAoKYGBge3IgbG9hZG1lLCBldmFsPUZBTFNFLCBpbmNsdWRlPUZBTFNFfQp0bXAgPC0gbG9hZG1lKGZpbGVuYW1lPXRoaXNfc2F2ZSkKYGBgCg==