Setup

library(ithi.utils)
load_base_libs()

library(methods)
library(ComplexHeatmap)
library(cluster)
library(entropy)
library(grid)
library(gridExtra)
library(gridBase)

library(ithi.meta)
library(ithi.figures)
library(ithi.utils)
library(ithi.supp)
library(ithi.clones)
library(ithi.xcr)
ihc_table_path <- snakemake@input$ihc_table
xcr_table_path <- snakemake@input$xcr_table
molecular_subtype_file <- snakemake@input$molsubtypes
tcr_diversity_file <- snakemake@input$tcr_diversity
bcr_diversity_file <- snakemake@input$bcr_diversity

tils_for_cluster <- snakemake@params$tils_for_cluster
all_tiltypes <- snakemake@params$all_tiltypes
db_path <- snakemake@params$db
annotation_colours <- ithi.figures::get_annotation_colours()
ihc_table <- fread(ihc_table_path)
molsubtypes <- fread(molecular_subtype_file)
xcr_table <- read_clonotypes(xcr_table_path, duplicates = FALSE, db_path = db_path)

Read 16.4% of 304822 rows
Read 55.8% of 304822 rows
Read 85.3% of 304822 rows
Read 304822 rows and 18 (of 18) columns from 0.070 GB file in 00:00:06

Analysis

This reviewer makes a great point here – it would make more sense for us to do this with our subtypes. My original intention was to emphasize novelty – i.e. in showing that C1 tumours have higher TCR diversity, which is not known AFAIK in the literature – but we could just as easily do this without own subtypes.

So let’s do so.

til_subtype_results <- ithi.supp::supp_molsubtype_immune_properties(ihc_table, 
    molsubtypes, xcr_table, tcr_diversity_file, bcr_diversity_file, db_path, 
    tiltypes = all_tiltypes, subtype_class = "til_clusters")
grid.newpage()
grid.draw(til_subtype_results$fig[[1]])

grid.newpage()
grid.draw(til_subtype_results$fig[[2]])

So it seems that, although S-TIL is more diverse than ES-TIL, the difference is not significant, except in the case of BCRs when using the D50 index. What that would mean is that BCR repertoires are dominated by rare clonotypes in S-TIL samples, to a greater degree than in ES-TIL and N-TIL samples.

Nevertheless, we can see a consistent trend towards higher TCR and BCR diversity values in S-TIL and ES-TIL subsets. This is a finding that may be validated by further studies/larger cohorts.

Next, we’ll just show the TIL densities in each of the TIL subtypes. This used to show TIL densities in each of the molecular subtypes.

grid.newpage()
grid.draw(til_subtype_results$combined_fig)

As expected, epithelial TIL densities are higher in ES-TIL, and stromal TIL densities are highest in S-TIL (but for CD8+’s and plasma comparable between S-TIL and ES-TIL).

Additionally, there’s another pretty interesting finding here – ES-TIL samples have the lowest proportion of private (site-specific) clonotypes. This could possibly be due to expanded clonotypes ‘crowding out’ the read space for less-expanded, site-specific i.e. ‘private’ clonotypes in the ES-TIL samples (reviewer 3’s hypothesis would probably be this, based on their comments).

LS0tCnRpdGxlOiAiVElMIGNsdXN0ZXJzOiBpbW11bmUgcHJvcGVydGllcyIKLS0tCiAgICAgICAgICAgICAgICAgICAgICAgIGBgYHtyLCBlY2hvPUZBTFNFLCBtZXNzYWdlPUZBTFNFLCB3YXJuaW5nPUZBTFNFfQoKIyMjIyMjIyMgU25ha2VtYWtlIGhlYWRlciAjIyMjIyMjIwpsaWJyYXJ5KG1ldGhvZHMpClNuYWtlbWFrZSA8LSBzZXRDbGFzcygKICAgICJTbmFrZW1ha2UiLAogICAgc2xvdHMgPSBjKAogICAgICAgIGlucHV0ID0gImxpc3QiLAogICAgICAgIG91dHB1dCA9ICJsaXN0IiwKICAgICAgICBwYXJhbXMgPSAibGlzdCIsCiAgICAgICAgd2lsZGNhcmRzID0gImxpc3QiLAogICAgICAgIHRocmVhZHMgPSAibnVtZXJpYyIsCiAgICAgICAgbG9nID0gImxpc3QiLAogICAgICAgIHJlc291cmNlcyA9ICJsaXN0IiwKICAgICAgICBjb25maWcgPSAibGlzdCIsCiAgICAgICAgcnVsZSA9ICJjaGFyYWN0ZXIiCiAgICApCikKc25ha2VtYWtlIDwtIFNuYWtlbWFrZSgKICAgIGlucHV0ID0gbGlzdCgnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvdGFibGVzL3J1bjIveGNyX3RhYmxlLnRzdicsICcvc2hhaGxhYi9hbHpoYW5nL3BpcGVsaW5lX291dHB1dHMvaXRoX2ltbXVuZS9taXhjci9taXhjcl9ydW5zL2l0aF8xXzJfMy9taXhjcjUvcG9zdHByb2Nlc3MvSUdIL3Bvc3RmaWx0ZXJfZGl2ZXJzaXR5X3N0YXRzL2RpdmVyc2l0eS5zdHJpY3QucmVzYW1wbGVkLnR4dCcsICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy90YWJsZXMvcnVuMi9tb2xzdWJ0eXBlcy50c3YnLCAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvdGFibGVzL3J1bjIvaWhjX3RhYmxlLnRzdicsICdub3RlYm9va3MvdGlsY2x1c3Rlcl9pbW11bmVwcm9wZXJ0aWVzLlJtZCcsICcvc2hhaGxhYi9hbHpoYW5nL3BpcGVsaW5lX291dHB1dHMvaXRoX2ltbXVuZS9taXhjci9taXhjcl9ydW5zL2l0aF8xXzJfMy9taXhjcjUvcG9zdHByb2Nlc3MvVFJCL3Bvc3RmaWx0ZXJfZGl2ZXJzaXR5X3N0YXRzL2RpdmVyc2l0eS5zdHJpY3QucmVzYW1wbGVkLnR4dCcsICJ4Y3JfdGFibGUiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL3RhYmxlcy9ydW4yL3hjcl90YWJsZS50c3YnLCAiYmNyX2RpdmVyc2l0eSIgPSAnL3NoYWhsYWIvYWx6aGFuZy9waXBlbGluZV9vdXRwdXRzL2l0aF9pbW11bmUvbWl4Y3IvbWl4Y3JfcnVucy9pdGhfMV8yXzMvbWl4Y3I1L3Bvc3Rwcm9jZXNzL0lHSC9wb3N0ZmlsdGVyX2RpdmVyc2l0eV9zdGF0cy9kaXZlcnNpdHkuc3RyaWN0LnJlc2FtcGxlZC50eHQnLCAibW9sc3VidHlwZXMiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL3RhYmxlcy9ydW4yL21vbHN1YnR5cGVzLnRzdicsICJpaGNfdGFibGUiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL3RhYmxlcy9ydW4yL2loY190YWJsZS50c3YnLCAibm90ZWJvb2siID0gJ25vdGVib29rcy90aWxjbHVzdGVyX2ltbXVuZXByb3BlcnRpZXMuUm1kJywgInRjcl9kaXZlcnNpdHkiID0gJy9zaGFobGFiL2FsemhhbmcvcGlwZWxpbmVfb3V0cHV0cy9pdGhfaW1tdW5lL21peGNyL21peGNyX3J1bnMvaXRoXzFfMl8zL21peGNyNS9wb3N0cHJvY2Vzcy9UUkIvcG9zdGZpbHRlcl9kaXZlcnNpdHlfc3RhdHMvZGl2ZXJzaXR5LnN0cmljdC5yZXNhbXBsZWQudHh0JyksCiAgICBvdXRwdXQgPSBsaXN0KCcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9yZXZpZXcvbm90ZWJvb2tzL3J1bjIvdGlsY2x1c3Rlcl9pbW11bmVwcm9wZXJ0aWVzLm5iLmh0bWwnKSwKICAgIHBhcmFtcyA9IGxpc3QoYygnVF9DRDhfZGVuc2l0eScsICdUX0NENF9kZW5zaXR5JywgJ1RfQ0QyMF9kZW5zaXR5JywgJ1RfUGxhc21hX2RlbnNpdHknLCAnRV9DRDhfZGVuc2l0eScsICdFX0NENF9kZW5zaXR5JywgJ0VfQ0QyMF9kZW5zaXR5JywgJ0VfUGxhc21hX2RlbnNpdHknLCAnU19DRDhfZGVuc2l0eScsICdTX0NENF9kZW5zaXR5JywgJ1NfQ0QyMF9kZW5zaXR5JywgJ1NfUGxhc21hX2RlbnNpdHknKSwgJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9tZXRhZGF0YS9kYi9pbW11bmVfcHJvamVjdC5zcWxpdGUzJywgYygnRV9DRDhfZGVuc2l0eScsICdFX0NENF9kZW5zaXR5JywgJ0VfQ0QyMF9kZW5zaXR5JywgJ0VfUGxhc21hX2RlbnNpdHknLCAnU19DRDhfZGVuc2l0eScsICdTX0NENF9kZW5zaXR5JywgJ1NfQ0QyMF9kZW5zaXR5JywgJ1NfUGxhc21hX2RlbnNpdHknKSwgJ3RpbGNsdXN0ZXJfaW1tdW5lcHJvcGVydGllc19hbmFseXNpcycsICJhbGxfdGlsdHlwZXMiID0gYygnVF9DRDhfZGVuc2l0eScsICdUX0NENF9kZW5zaXR5JywgJ1RfQ0QyMF9kZW5zaXR5JywgJ1RfUGxhc21hX2RlbnNpdHknLCAnRV9DRDhfZGVuc2l0eScsICdFX0NENF9kZW5zaXR5JywgJ0VfQ0QyMF9kZW5zaXR5JywgJ0VfUGxhc21hX2RlbnNpdHknLCAnU19DRDhfZGVuc2l0eScsICdTX0NENF9kZW5zaXR5JywgJ1NfQ0QyMF9kZW5zaXR5JywgJ1NfUGxhc21hX2RlbnNpdHknKSwgImRiIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvbWV0YWRhdGEvZGIvaW1tdW5lX3Byb2plY3Quc3FsaXRlMycsICJ0aWxzX2Zvcl9jbHVzdGVyIiA9IGMoJ0VfQ0Q4X2RlbnNpdHknLCAnRV9DRDRfZGVuc2l0eScsICdFX0NEMjBfZGVuc2l0eScsICdFX1BsYXNtYV9kZW5zaXR5JywgJ1NfQ0Q4X2RlbnNpdHknLCAnU19DRDRfZGVuc2l0eScsICdTX0NEMjBfZGVuc2l0eScsICdTX1BsYXNtYV9kZW5zaXR5JyksICJuYW1lIiA9ICd0aWxjbHVzdGVyX2ltbXVuZXByb3BlcnRpZXNfYW5hbHlzaXMnKSwKICAgIHdpbGRjYXJkcyA9IGxpc3QoKSwKICAgIHRocmVhZHMgPSAxLAogICAgbG9nID0gbGlzdCgnL3NoYWhsYWIvYWx6aGFuZy9jbHVzdHRtcC9wYXBlcnJldmlldzIvbm90ZWJvb2tzL3RpbGNsdXN0ZXJfaW1tdW5lcHJvcGVydGllc19hbmFseXNpcy5sb2cnKSwKICAgIHJlc291cmNlcyA9IGxpc3QoKSwKICAgIGNvbmZpZyA9IGxpc3QoImFsbF90aWx0eXBlcyIgPSBjKCdUX0NEOF9kZW5zaXR5JywgJ1RfQ0Q0X2RlbnNpdHknLCAnVF9DRDIwX2RlbnNpdHknLCAnVF9QbGFzbWFfZGVuc2l0eScsICdFX0NEOF9kZW5zaXR5JywgJ0VfQ0Q0X2RlbnNpdHknLCAnRV9DRDIwX2RlbnNpdHknLCAnRV9QbGFzbWFfZGVuc2l0eScsICdTX0NEOF9kZW5zaXR5JywgJ1NfQ0Q0X2RlbnNpdHknLCAnU19DRDIwX2RlbnNpdHknLCAnU19QbGFzbWFfZGVuc2l0eScpLCAibmFub3N0cmluZ19hbm5vdGF0aW9ucyIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL2RhdGEvZXhwcmVzc2lvbi9uYW5vc3RyaW5nL3BhbmNhbmNlcl9hbm5vdGF0aW9ucy50c3YnLCAiZGlzdGFuY2VfbWV0aG9kIiA9ICdob3JuJywgImloY190YWJsZSIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvdGFibGVzL3J1bjIvaWhjX3RhYmxlLnRzdicsICJhcnJheV9leHByZXNzaW9uX2ZpbGUiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9kYXRhL2V4cHJlc3Npb24vYXJyYXkvZ2VuZV9leHByc19ybWFfYmF0Y2hfY29ycmVjdGVkLnR4dCcsICJjbG9uZV9icmFuY2hfbGVuZ3RocyIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvdGFibGVzL3J1bjIvY2xvbmVzL2JyYW5jaF9kYXRhLnRzdicsICJpdGhfc3RhdHMiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL3RhYmxlcy9ydW4yL2l0aF9zdGF0aXN0aWNzLnRzdicsICJtb2xzdWJ0eXBlcyIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvdGFibGVzL3J1bjIvbW9sc3VidHlwZXMudHN2JywgImNsb25lX3ByZXZhbGVuY2VzIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy90YWJsZXMvcnVuMi9jbG9uZXMvY2xvbmVfZGF0YS50c3YnLCAicmVmc2VxX2dlbmVfZmlsZSIgPSAnL3NoYWhsYWIvYWx6aGFuZy9kYXRhL2dlbm9tZS9oZzE5L3JlZnNlcV9nZW5lcy5iZWQnLCAiYmVuY2htYXJrZGlyIiA9ICcvc2hhaGxhYi9hbHpoYW5nL2JlbmNobWFya3MvcGFwZXJyZXZpZXcyJywgIm5lb2VkaXRpbmdfb3V0ZGlyIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3BpcGVsaW5lX291dHB1dHMvaXRoX2ltbXVuZS9uZW9lZGl0aW5nL3J1bjYnLCAic29tYXRpY19jb2RpbmdfcmVzdWx0X2RpciIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvdGFibGVzL3J1bjIvc29tYXRpY19jb2RpbmdfdmFyaWFudHMnLCAiaWNnY19zdWJ0eXBlcyIgPSAnL3NoYWhsYWIvYWx6aGFuZy9kYXRhL0lDR0MvaWNnY19wcmltYXJ5X3R1bW91cl9zdWJ0eXBlcy50c3YnLCAicm9vbmV5X211dHNpZ2N2X2ZpbGUiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9leHRlcm5hbC9vdGhlcl9wYXBlcnMvbW1jNi54bHN4JywgImltYWdlX3N1bW1hcnkiID0gJy9zaGFobGFiL2FsemhhbmcvZGF0YS9pdGhpL3l1YW5faGVjcl9pbWFnZV9yZXN1bHRzLmNzdicsICJkYiIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL21ldGFkYXRhL2RiL2ltbXVuZV9wcm9qZWN0LnNxbGl0ZTMnLCAiY29weW51bWJlcl90YWJsZSIgPSAnL3NoYWhsYWIvYWx6aGFuZy9kYXRhL2l0aGkvbWFzdGVyX2NvcHludW1iZXJfZmlsZS50c3YnLCAiYnJlYWtwb2ludF90YWJsZSIgPSAnL3NoYWhsYWIvYW1jcGhlcnNvbi9wcm9qZWN0cy9pdGgzL2l0aDMvbm90ZWJvb2tzL2Jlc3Bva2UvaXRoX2JyZWFrcG9pbnRzLnRzdicsICJ0aWxzX2Zvcl92YXJpYWJpbGl0eSIgPSBjKCdUX0NEOF9kZW5zaXR5JywgJ1RfQ0Q0X2RlbnNpdHknLCAnVF9DRDIwX2RlbnNpdHknLCAnVF9QbGFzbWFfZGVuc2l0eScpLCAic252X2NsdXN0ZXJfZGlyIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy90YWJsZXMvcnVuMi9jbG9uZXMvc252X2NsdXN0ZXInLCAiaWNnY19zcGVjaW1lbiIgPSAnL3NoYWhsYWIvYWx6aGFuZy9kYXRhL0lDR0Mvc3BlY2ltZW4udHN2JywgImNsb25lX3RyZWVzIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy90YWJsZXMvcnVuMi9jbG9uZXMvdHJlZV9kYXRhLnRzdicsICJjbG9sYV9yZXN1bHRfZmlsZSIgPSAnL3NoYWhsYWIvYWx6aGFuZy9waXBlbGluZV9vdXRwdXRzL2l0aF9pbW11bmUvY2xvbGEvcnVuNC9jbG9sYV9jb25kZW5zZWRfcmVzdWx0cy9iZXRhL2Nsb2xhX3Jlc3VsdHMudHN2JywgImtub3duX3N1YnR5cGVzX2FycmF5IiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvZGF0YS9leHByZXNzaW9uL2FycmF5L3N1YnR5cGVzL2tub3duX3N1YnR5cGVzLnRzdicsICJ0b3RhbF90aWx0eXBlcyIgPSBjKCdUX0NEOF9kZW5zaXR5JywgJ1RfQ0Q0X2RlbnNpdHknLCAnVF9DRDIwX2RlbnNpdHknLCAnVF9QbGFzbWFfZGVuc2l0eScpLCAicGF0aWVudHNfZm9yX2Nsb25hbCIgPSBjKDEsIDIsIDMsIDQsIDcsIDksIDEwLCAxMSwgMTIsIDEzLCAxNCwgMTUsIDE2LCAxNyksICJ0aWxfY2x1c3RlcnNfb3V0cHV0IiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9pbnRlcm1lZGlhdGVzL3J1bjIvdGlsX2NsdXN0ZXJzX291dHB1dC50eHQnLCAibmFub3N0cmluZ19kYXRhIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcmVzdWx0cy9uYW5vc3RyaW5nX3Jlc3VsdHMvaXRoX2Z1bGwvcWMvbGltbWFfcXVhbnRpbGUvbm9ybWFsaXplZF9leHByZXNzaW9uX3ZvYV9sYWJlbHNfZmlsdGVyZWQudHN2JywgImZpbm5oZV9waXBlbGluZV9yZXN1bHRzX2RpciIgPSAnL3NoYWhsYWIvYWx6aGFuZy9waXBlbGluZV9vdXRwdXRzL2l0aF9pbW11bmUvZmlubmhlL3J1bjEnLCAidGlsY2x1c3Rlcl9zdXBlcnZpc2VkX2lweW5iIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmV2aWV3L2lweS90aWxjbHVzdGVyX3N1cGVydmlzZWRtdWx0aWNsYXNzLmlweW5iJywgIm1tY3RtX2ZpbmFsX3BhdGllbnRfZGlyIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcmVzdWx0cy9tbWN0bV9yZXN1bHRzL2l0aF9ieS1wYXRpZW50X3dpdGgtb3YnLCAidmFyaWFiaWxpdHlfdHlwZSIgPSAnc3RhYmlsaXplJywgIml0aF9pY2djX2JjIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy90YWJsZXMvcnVuMi9pdGhfaWNnY19tZXJnZWRfYmMudHN2JywgInRpbHNfZm9yX2NsdXN0ZXIiID0gYygnRV9DRDhfZGVuc2l0eScsICdFX0NENF9kZW5zaXR5JywgJ0VfQ0QyMF9kZW5zaXR5JywgJ0VfUGxhc21hX2RlbnNpdHknLCAnU19DRDhfZGVuc2l0eScsICdTX0NENF9kZW5zaXR5JywgJ1NfQ0QyMF9kZW5zaXR5JywgJ1NfUGxhc21hX2RlbnNpdHknKSwgImloY19mZWF0dXJlc19vdXRwdXQiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL2ludGVybWVkaWF0ZXMvcnVuMi9paGNfZmVhdHVyZXNfb3V0cHV0LnR4dCcsICJpdGhfc3RhdF90eXBlcyIgPSBjKCdlbnRyb3B5JywgJ3Bvc3Rwcm9jZXNzZWRfZGl2ZXJnZW5jZScsICdjb21iaW5lZF9pdGhfbm9ybWFsaXplZCcsICdwcm9wb3J0aW9uX3N1YmNsb25hbCcpLCAiaGVfcmVzdWx0c19kaXIiID0gJy9zaGFobGFiL2FsemhhbmcvZGF0YS9pdGhpL2Zpbm5fcmVzdWx0cy9oZV9vdXRwdXRfTm92MjknLCAiaW1hZ2Vfc3VtbWFyeTIiID0gJy9zaGFobGFiL2FsemhhbmcvZGF0YS9pdGhpL3l1YW5faGVjcl9pbWFnZV9yZXN1bHRzXzIuY3N2JywgInNudl90YWJsZSIgPSAnL3NoYWhsYWIvYW1jcGhlcnNvbi9wcm9qZWN0cy9pdGgzL2l0aDMvbm90ZWJvb2tzL2Jlc3Bva2UvaXRoX3NudnMudHN2JywgInR1bW91cl9wdXJpdHkiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL3RhYmxlcy9ydW4yL3R1bW91cl9wdXJpdHkudHN2JywgImJjcl9kaXZlcnNpdHkiID0gJy9zaGFobGFiL2FsemhhbmcvcGlwZWxpbmVfb3V0cHV0cy9pdGhfaW1tdW5lL21peGNyL21peGNyX3J1bnMvaXRoXzFfMl8zL21peGNyNS9wb3N0cHJvY2Vzcy9JR0gvcG9zdGZpbHRlcl9kaXZlcnNpdHlfc3RhdHMvZGl2ZXJzaXR5LnN0cmljdC5yZXNhbXBsZWQudHh0JywgImlncGFydGl0aW9uX291dGRpciIgPSAnL3NoYWhsYWIvYWx6aGFuZy9waXBlbGluZV9vdXRwdXRzL2l0aF9pbW11bmUvaWdwYXJ0aXRpb24vcnVuMjInLCAibm90ZWJvb2tfZGlyIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9yZXZpZXcvbm90ZWJvb2tzL3J1bjInLCAicmVtaXh0X2NlbGx1bGFyaXR5X3Bsb2lkeSIgPSAnL3NoYWhsYWIvYWx6aGFuZy9wcm9qZWN0cy9JVEhfSW1tdW5lL3BhcGVyL3Jlc3VsdHMvdGFibGVzL3J1bjIvcmVtaXh0X2NlbGx1bGFyaXR5X3Bsb2lkeS50c3YnLCAidGFibGVfZGlyIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy9yZXZpZXcvdGFibGVzL3J1bjInLCAiZXBpdG9wZXNfdW5pcXVlX2ZpbHRlcmVkIiA9ICcvc2hhaGxhYi9hbHpoYW5nL3Byb2plY3RzL0lUSF9JbW11bmUvcGFwZXIvcmVzdWx0cy90YWJsZXMvcnVuMi9lcGl0b3Blc191bmlxdWVfZmlsdGVyZWQudHN2JywgInByZXZhbGVuY2VfdGhyZXNob2xkIiA9IDAuMDEsICJ4Y3JfdGFibGUiID0gJy9zaGFobGFiL2FsemhhbmcvcHJvamVjdHMvSVRIX0ltbXVuZS9wYXBlci9yZXN1bHRzL3RhYmxlcy9ydW4yL3hjcl90YWJsZS50c3YnLCAibG9nZGlyIiA9ICcvc2hhaGxhYi9hbHpoYW5nL2NsdXN0dG1wL3BhcGVycmV2aWV3MicsICJ0Y3JfZGl2ZXJzaXR5IiA9ICcvc2hhaGxhYi9hbHpoYW5nL3BpcGVsaW5lX291dHB1dHMvaXRoX2ltbXVuZS9taXhjci9taXhjcl9ydW5zL2l0aF8xXzJfMy9taXhjcjUvcG9zdHByb2Nlc3MvVFJCL3Bvc3RmaWx0ZXJfZGl2ZXJzaXR5X3N0YXRzL2RpdmVyc2l0eS5zdHJpY3QucmVzYW1wbGVkLnR4dCcpLAogICAgcnVsZSA9ICd0aWxjbHVzdGVyX2ltbXVuZXByb3BlcnRpZXNfYW5hbHlzaXMnCikKIyMjIyMjIyMgT3JpZ2luYWwgc2NyaXB0ICMjIyMjIyMjIwoKICAgICAgICAgICAgICAgICAgICAgICAgYGBgCgoKIyMgU2V0dXAKCmBgYHtyIGdsb2JhbF9jaHVua19vcHRpb25zLCBpbmNsdWRlPUZBTFNFfQprbml0cjo6b3B0c19jaHVuayRzZXQoZWNobyA9IFRSVUUsIHRpZHk9VFJVRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgY2FjaGU9VFJVRSkgI2NhY2hlPVRSVUUKYGBgCgpgYGB7cn0KbGlicmFyeShpdGhpLnV0aWxzKQpsb2FkX2Jhc2VfbGlicygpCgpsaWJyYXJ5KG1ldGhvZHMpCmxpYnJhcnkoQ29tcGxleEhlYXRtYXApCmxpYnJhcnkoY2x1c3RlcikKbGlicmFyeShlbnRyb3B5KQpsaWJyYXJ5KGdyaWQpCmxpYnJhcnkoZ3JpZEV4dHJhKQpsaWJyYXJ5KGdyaWRCYXNlKQoKbGlicmFyeShpdGhpLm1ldGEpCmxpYnJhcnkoaXRoaS5maWd1cmVzKQpsaWJyYXJ5KGl0aGkudXRpbHMpCmxpYnJhcnkoaXRoaS5zdXBwKQpsaWJyYXJ5KGl0aGkuY2xvbmVzKQpsaWJyYXJ5KGl0aGkueGNyKQpgYGAKCmBgYHtyfQppaGNfdGFibGVfcGF0aCA8LSBzbmFrZW1ha2VAaW5wdXQkaWhjX3RhYmxlCnhjcl90YWJsZV9wYXRoIDwtIHNuYWtlbWFrZUBpbnB1dCR4Y3JfdGFibGUKbW9sZWN1bGFyX3N1YnR5cGVfZmlsZSA8LSBzbmFrZW1ha2VAaW5wdXQkbW9sc3VidHlwZXMKdGNyX2RpdmVyc2l0eV9maWxlIDwtIHNuYWtlbWFrZUBpbnB1dCR0Y3JfZGl2ZXJzaXR5CmJjcl9kaXZlcnNpdHlfZmlsZSA8LSBzbmFrZW1ha2VAaW5wdXQkYmNyX2RpdmVyc2l0eQoKdGlsc19mb3JfY2x1c3RlciA8LSBzbmFrZW1ha2VAcGFyYW1zJHRpbHNfZm9yX2NsdXN0ZXIKYWxsX3RpbHR5cGVzIDwtIHNuYWtlbWFrZUBwYXJhbXMkYWxsX3RpbHR5cGVzCmRiX3BhdGggPC0gc25ha2VtYWtlQHBhcmFtcyRkYgpgYGAKCmBgYHtyfQphbm5vdGF0aW9uX2NvbG91cnMgPC0gaXRoaS5maWd1cmVzOjpnZXRfYW5ub3RhdGlvbl9jb2xvdXJzKCkKaWhjX3RhYmxlIDwtIGZyZWFkKGloY190YWJsZV9wYXRoKQptb2xzdWJ0eXBlcyA8LSBmcmVhZChtb2xlY3VsYXJfc3VidHlwZV9maWxlKQp4Y3JfdGFibGUgPC0gcmVhZF9jbG9ub3R5cGVzKHhjcl90YWJsZV9wYXRoLCBkdXBsaWNhdGVzID0gRkFMU0UsIGRiX3BhdGggPSBkYl9wYXRoKQpgYGAKCiMjIEFuYWx5c2lzCgpUaGlzIHJldmlld2VyIG1ha2VzIGEgZ3JlYXQgcG9pbnQgaGVyZSAtLSBpdCB3b3VsZCBtYWtlIG1vcmUgc2Vuc2UgZm9yIHVzIHRvIGRvIHRoaXMgd2l0aCBvdXIgc3VidHlwZXMuIE15IG9yaWdpbmFsIGludGVudGlvbiB3YXMgdG8gZW1waGFzaXplIG5vdmVsdHkgLS0gaS5lLiBpbiBzaG93aW5nIHRoYXQgQzEgdHVtb3VycyBoYXZlIGhpZ2hlciBUQ1IgZGl2ZXJzaXR5LCB3aGljaCBpcyBub3Qga25vd24gQUZBSUsgaW4gdGhlIGxpdGVyYXR1cmUgLS0gYnV0IHdlIGNvdWxkIGp1c3QgYXMgZWFzaWx5IGRvIHRoaXMgd2l0aG91dCBvd24gc3VidHlwZXMuIAoKU28gbGV0J3MgZG8gc28uIAoKYGBge3IsIHJlc3VsdHMgPSAnaGlkZSd9CnRpbF9zdWJ0eXBlX3Jlc3VsdHMgPC0gaXRoaS5zdXBwOjpzdXBwX21vbHN1YnR5cGVfaW1tdW5lX3Byb3BlcnRpZXMoaWhjX3RhYmxlLCBtb2xzdWJ0eXBlcywgeGNyX3RhYmxlLCB0Y3JfZGl2ZXJzaXR5X2ZpbGUsIGJjcl9kaXZlcnNpdHlfZmlsZSwgZGJfcGF0aCwgdGlsdHlwZXMgPSBhbGxfdGlsdHlwZXMsIHN1YnR5cGVfY2xhc3MgPSAidGlsX2NsdXN0ZXJzIikKYGBgCgpgYGB7cn0KZ3JpZC5uZXdwYWdlKCkKZ3JpZC5kcmF3KHRpbF9zdWJ0eXBlX3Jlc3VsdHMkZmlnW1sxXV0pCmBgYAoKCmBgYHtyfQpncmlkLm5ld3BhZ2UoKQpncmlkLmRyYXcodGlsX3N1YnR5cGVfcmVzdWx0cyRmaWdbWzJdXSkKYGBgCgpTbyBpdCBzZWVtcyB0aGF0LCBhbHRob3VnaCBTLVRJTCBpcyBtb3JlIGRpdmVyc2UgdGhhbiBFUy1USUwsIHRoZSBkaWZmZXJlbmNlIGlzIG5vdCBzaWduaWZpY2FudCwgZXhjZXB0IGluIHRoZSBjYXNlIG9mIEJDUnMgd2hlbiB1c2luZyB0aGUgRDUwIGluZGV4LiBXaGF0IHRoYXQgd291bGQgbWVhbiBpcyB0aGF0IEJDUiByZXBlcnRvaXJlcyBhcmUgZG9taW5hdGVkIGJ5IHJhcmUgY2xvbm90eXBlcyBpbiBTLVRJTCBzYW1wbGVzLCB0byBhIGdyZWF0ZXIgZGVncmVlIHRoYW4gaW4gRVMtVElMIGFuZCBOLVRJTCBzYW1wbGVzLiAKCk5ldmVydGhlbGVzcywgd2UgY2FuIHNlZSBhIGNvbnNpc3RlbnQgdHJlbmQgdG93YXJkcyBoaWdoZXIgVENSIGFuZCBCQ1IgZGl2ZXJzaXR5IHZhbHVlcyBpbiBTLVRJTCBhbmQgRVMtVElMIHN1YnNldHMuIFRoaXMgaXMgYSBmaW5kaW5nIHRoYXQgbWF5IGJlIHZhbGlkYXRlZCBieSBmdXJ0aGVyIHN0dWRpZXMvbGFyZ2VyIGNvaG9ydHMuIAoKCk5leHQsIHdlJ2xsIGp1c3Qgc2hvdyB0aGUgVElMIGRlbnNpdGllcyBpbiBlYWNoIG9mIHRoZSBUSUwgc3VidHlwZXMuIFRoaXMgdXNlZCB0byBzaG93IFRJTCBkZW5zaXRpZXMgaW4gZWFjaCBvZiB0aGUgbW9sZWN1bGFyIHN1YnR5cGVzLiAKCmBgYHtyLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDE5fQpncmlkLm5ld3BhZ2UoKQpncmlkLmRyYXcodGlsX3N1YnR5cGVfcmVzdWx0cyRjb21iaW5lZF9maWcpCmBgYAoKQXMgZXhwZWN0ZWQsIGVwaXRoZWxpYWwgVElMIGRlbnNpdGllcyBhcmUgaGlnaGVyIGluIEVTLVRJTCwgYW5kIHN0cm9tYWwgVElMIGRlbnNpdGllcyBhcmUgaGlnaGVzdCBpbiBTLVRJTCAoYnV0IGZvciBDRDgrJ3MgYW5kIHBsYXNtYSBjb21wYXJhYmxlIGJldHdlZW4gUy1USUwgYW5kIEVTLVRJTCkuIAoKQWRkaXRpb25hbGx5LCB0aGVyZSdzIGFub3RoZXIgcHJldHR5IGludGVyZXN0aW5nIGZpbmRpbmcgaGVyZSAtLSBFUy1USUwgc2FtcGxlcyBoYXZlIHRoZSBsb3dlc3QgcHJvcG9ydGlvbiBvZiBwcml2YXRlIChzaXRlLXNwZWNpZmljKSBjbG9ub3R5cGVzLiBUaGlzIGNvdWxkIHBvc3NpYmx5IGJlIGR1ZSB0byBleHBhbmRlZCBjbG9ub3R5cGVzICdjcm93ZGluZyBvdXQnIHRoZSByZWFkIHNwYWNlIGZvciBsZXNzLWV4cGFuZGVkLCBzaXRlLXNwZWNpZmljIGkuZS4gJ3ByaXZhdGUnIGNsb25vdHlwZXMgaW4gdGhlIEVTLVRJTCBzYW1wbGVzIChyZXZpZXdlciAzJ3MgaHlwb3RoZXNpcyB3b3VsZCBwcm9iYWJseSBiZSB0aGlzLCBiYXNlZCBvbiB0aGVpciBjb21tZW50cykuIAoK