This document hopes to be a useful benchmark for a “toy” dataset, namely the network of 47 statistics journals studied in the paper Varin, C., Cattelan, M. and Firth, D. (2016), “Statistical modelling of citation exchange between statistics journals”. J. R. Stat. Soc. A, 179: 1–63. doi:10.1111/rssa.12124.
It isn’t always clear how the various implementations of community detection algorithms handle cases of directed and undirected graphs and the difference between weighted edges or multiple unweighted edges. Therefore, in this document we will try each of the four combinations just to see what happens. Where igraph algorithms are not implemented for weighted or directed graphs, they will throw an error, which we have reproduced under the respective tabs. Beware: just because the algorithm does not throw an error does not necessarily mean that directions or weights are actually taken into account.
Self-citations have not been explicitly removed before performing any of the procedures below (though some algorithms may implicitly or explicitly ignore them). I might try removing self-citations later to see if it makes any noticeable difference to the results.
Also to do: nice minimal plots so we don’t have to read lists/tables all day. Update: scroll down to see some visualisations.
Infomap algorithm
Directed multi-edge
- ANZS, Bcs, CSSC, CSTM, EES, Envr, JAS, JBS, JRSS-B, JSCS, JSS, StMed, StNee, StPap, SPL
- AmS, Bka, Biost, CSDA, JCGS, JRSS-A, JSPI, Mtka, SJS, StataJ, StSci
- BioJ, CJS, JASA, JNS, JRSS-C, LDA, StCmp, Stats, SMMR, StSin, Tech, Test
- AISM, AoS, Bern, CmpSt, ISR, JABES, JMA, JTSA, StMod
Directed weighted
- AmS, AISM, AoS, ANZS, Bern, BioJ, Bcs, Bka, Biost, CJS, CSSC, CSTM, CmpSt, CSDA, EES, Envr, ISR, JABES, JASA, JAS, JBS, JCGS, JMA, JNS, JRSS-A, JRSS-B, JRSS-C, JSCS, JSPI, JSS, JTSA, LDA, Mtka, SJS, StataJ, StCmp, Stats, StMed, SMMR, StMod, StNee, StPap, SPL, StSci, StSin, Tech, Test
Undirected multi-edge
- AoS, StMed
- JASA, StSci
- Bka, JMA
- CSDA, Test
- JNS, JSPI
- Bern, Bcs
- Biost, CSTM
- JAS, SPL
- JRSS-A, JRSS-B
- JRSS-C, StSin
- BioJ, JSCS
- LDA, SJS
- AISM, Mtka, StNee
- CmpSt, JCGS
- CSSC, JTSA
- CJS, SMMR
- JBS, Tech
- StCmp, StMod
- Envr, JSS
- Stats, StPap
- AmS, EES
- ANZS, JABES
- ISR, StataJ
Undirected weighted
- AmS, AISM, AoS, ANZS, Bern, BioJ, Bcs, Bka, Biost, CJS, CSSC, CSTM, CmpSt, CSDA, EES, Envr, ISR, JABES, JASA, JAS, JBS, JCGS, JMA, JNS, JRSS-A, JRSS-B, JRSS-C, JSCS, JSPI, JSS, JTSA, LDA, Mtka, SJS, StataJ, StCmp, Stats, StMed, SMMR, StMod, StNee, StPap, SPL, StSci, StSin, Tech, Test
Agglomerative hierarchical clustering
Directed, complete-linkage
- AmS
- AISM, JTSA, Stats, SPL
- AoS, Bern, CJS, JMA, JNS
- ANZS, JSPI, Mtka, Tech, Test
- BioJ, JBS
- Bcs, Biost, JRSS-A, JRSS-C, LDA, StMed, SMMR
- Bka, JASA, JRSS-B, SJS, StSin
- CSSC, CSTM, JAS, JSCS, StPap
- CmpSt, CSDA, JCGS, StCmp
- EES
- Envr, JABES
- ISR
- JSS
- StataJ
- StMod, StSci
- StNee
Undirected, complete-linkage
- AmS, ISR
- AISM, ANZS, CSTM, JSPI, JTSA, Mtka, Stats, StPap, SPL
- AoS, Bern, Bka, CJS, JASA, JCGS, JMA, JNS, JRSS-B, SJS, StCmp, StNee, StSin, Test
- BioJ, Bcs, Biost, JBS, JRSS-A, JRSS-C, LDA, StMed, SMMR, StMod, StSci
- CSSC, CmpSt, CSDA, JAS, JSCS, Tech
- EES, Envr, JABES
- JSS
- StataJ
Hierarchical clustering with complete linkage, applied to the undirected Pearson correlation matrix, should exactly reproduce the results of Varin et al (2016).
Edge betweenness
Directed multi-edge
- AmS
- AISM
- AoS, JMA, StSin
- ANZS
- Bern
- BioJ
- Bcs, StMed
- Bka
- Biost
- CJS
- CSSC
- CSTM
- CmpSt
- CSDA, JASA
- EES
- Envr
- ISR
- JABES
- JAS
- JBS
- JCGS
- JNS
- JRSS-A
- JRSS-B
- JRSS-C
- JSCS
- JSPI
- JSS
- JTSA
- LDA
- Mtka
- SJS
- StataJ
- StCmp
- Stats
- SMMR
- StMod
- StNee
- StPap
- SPL
- StSci
- Tech
- Test
Directed weighted
- AmS
- AISM
- AoS
- ANZS
- Bern
- BioJ
- Bcs
- Bka
- Biost
- CJS
- CSSC
- CSTM
- CmpSt
- CSDA
- EES
- Envr
- ISR
- JABES
- JASA
- JAS
- JBS
- JCGS
- JMA, JNS, JRSS-B, JSPI, SJS, StCmp, SPL, StSin, Tech, Test
- JRSS-A
- JRSS-C
- JSCS
- JSS
- JTSA
- LDA
- Mtka
- StataJ
- Stats
- StMed
- SMMR
- StMod
- StNee
- StPap
- StSci
Undirected multi-edge
- AmS
- AISM
- AoS, Bka, CSDA, JASA, JMA, JRSS-B, JSPI, StSin
- ANZS
- Bern
- BioJ
- Bcs, StMed
- Biost
- CJS
- CSSC
- CSTM
- CmpSt
- EES
- Envr
- ISR
- JABES
- JAS
- JBS
- JCGS
- JNS
- JRSS-A
- JRSS-C
- JSCS
- JSS
- JTSA
- LDA
- Mtka
- SJS
- StataJ
- StCmp
- Stats
- SMMR
- StMod
- StNee
- StPap
- SPL
- StSci
- Tech
- Test
Undirected weighted
- AmS
- AISM
- AoS
- ANZS
- Bern
- BioJ
- Bcs
- Bka
- Biost
- CJS
- CSSC
- CSTM
- CmpSt
- CSDA
- EES
- Envr
- ISR
- JABES
- JASA
- JAS
- JBS
- JCGS, StCmp, StSci
- JMA
- JNS
- JRSS-A
- JRSS-B, SMMR
- JRSS-C
- JSCS, Mtka, Stats, StPap, SPL
- JSPI
- JSS
- JTSA
- LDA, StSin
- SJS
- StataJ
- StMed
- StMod
- StNee
- Tech
- Test
Modularity optimisation: fast and greedy
Directed multi-edge
Looks like an error! Here is the message:
At fast_community.c:538 : fast greedy community detection works for undirected graphs only, Unimplemented function call
Directed weighted
Looks like an error! Here is the message:
At fast_community.c:538 : fast greedy community detection works for undirected graphs only, Unimplemented function call
Undirected multi-edge
Looks like an error! Here is the message:
At fast_community.c:553 : fast-greedy community finding works only on graphs without multiple edges, Invalid value
Undirected weighted
- AISM, ANZS, CSSC, CSTM, JAS, JMA, JNS, JSCS, JSPI, JTSA, Mtka, Stats, StNee, StPap, SPL, Tech
- CmpSt, CSDA, JSS
- AmS, ISR
- EES, Envr, JABES
- AoS, Bern, Bka, CJS, JASA, JCGS, JRSS-B, SJS, StCmp, StSin, Test
- BioJ, Bcs, Biost, JBS, JRSS-A, JRSS-C, LDA, StMed, SMMR, StMod, StSci
- StataJ
Modularity optimisation: Louvain method (Blondel et al)
Directed multi-edge
Looks like an error! Here is the message:
At community.c:2672 : multi-level community detection works for undirected graphs only, Unimplemented function call
Directed weighted
Looks like an error! Here is the message:
At community.c:2672 : multi-level community detection works for undirected graphs only, Unimplemented function call
Undirected multi-edge
- EES, Envr, JABES
- CmpSt, CSDA, JSS
- AISM, ANZS, CSSC, CSTM, JAS, JMA, JNS, JSCS, JSPI, JTSA, Mtka, Stats, StNee, StPap, SPL, Tech
- StataJ
- BioJ, Bcs, Biost, JBS, JRSS-A, JRSS-C, LDA, StMed, SMMR, StMod, StSci
- AmS, ISR
- AoS, Bern, Bka, CJS, JASA, JCGS, JRSS-B, SJS, StCmp, StSin, Test
Undirected weighted
- EES, Envr, JABES
- CmpSt, CSDA, JSS
- AISM, ANZS, CSSC, CSTM, JAS, JMA, JNS, JSCS, JSPI, JTSA, Mtka, Stats, StNee, StPap, SPL, Tech
- StataJ
- BioJ, Bcs, Biost, JBS, JRSS-A, JRSS-C, LDA, StMed, SMMR, StMod, StSci
- AmS, ISR
- AoS, Bern, Bka, CJS, JASA, JCGS, JRSS-B, SJS, StCmp, StSin, Test
Spinglass method
Directed multi-edge
- ANZS, BioJ, CmpSt, Envr, JABES, JAS, JCGS, JSS, StCmp, StSci, Tech
- AISM, Bern, CJS, CSSC, CSTM, JASA, JNS, JSCS, JTSA, Mtka, SJS, Stats, StPap, SPL, StSin, Test
- AmS, AoS, Bcs, Bka, Biost, CSDA, EES, ISR, JBS, JMA, JRSS-A, JRSS-B, JRSS-C, JSPI, LDA, StataJ, StMed, SMMR, StMod, StNee
Directed weighted
- AmS, BioJ, EES, ISR, JAS, JBS, JRSS-A, JRSS-C, JSS, LDA, SJS, StataJ, StMed, SMMR, StMod, StSci
- AISM, CSSC, CSTM, CmpSt, CSDA, JMA, JNS, JSCS, JSPI, JTSA, Mtka, Stats, StPap, SPL, StSin, Tech, Test
- AoS, ANZS, Bern, Bcs, Bka, Biost, CJS, Envr, JABES, JASA, JCGS, JRSS-B, StCmp, StNee
Undirected multi-edge
- ANZS, BioJ, CmpSt, Envr, JABES, JAS, JCGS, JSS, StCmp, StSci, Tech
- AISM, Bern, CJS, CSSC, CSTM, JASA, JNS, JSCS, JTSA, Mtka, SJS, Stats, StPap, SPL, StSin, Test
- AmS, AoS, Bcs, Bka, Biost, CSDA, EES, ISR, JBS, JMA, JRSS-A, JRSS-B, JRSS-C, JSPI, LDA, StataJ, StMed, SMMR, StMod, StNee
Undirected weighted
- AISM, ANZS, CSSC, CSTM, CmpSt, CSDA, ISR, JAS, JMA, JNS, JSCS, JSPI, JTSA, Mtka, Stats, StNee, StPap, SPL, Tech
- AoS, Bern, Bka, CJS, Envr, JASA, JCGS, JRSS-B, SJS, StCmp, StSin, Test
- AmS, BioJ, Bcs, Biost, EES, JABES, JBS, JRSS-A, JRSS-C, JSS, LDA, StataJ, StMed, SMMR, StMod, StSci
Random walks (walktrap)
Based on random walks of 6 steps.
See Pascal Pons, Matthieu Latapy: Computing communities in large networks using random walks, http://arxiv.org/abs/physics/0512106
Directed multi-edge
- AmS, BioJ, Bcs, Biost, EES, JABES, JBS, JRSS-A, JRSS-C, JSS, LDA, StMed, SMMR, StMod, StSci
- AISM, AoS, ANZS, Bern, Bka, CJS, CSSC, CSTM, CmpSt, CSDA, Envr, ISR, JASA, JAS, JCGS, JMA, JNS, JRSS-B, JSCS, JSPI, JTSA, Mtka, SJS, StCmp, Stats, StNee, StPap, SPL, StSin, Tech, Test
- StataJ
Directed weighted
- AmS, BioJ, Bcs, Biost, EES, JABES, JBS, JRSS-A, JRSS-C, JSS, LDA, StMed, SMMR, StMod, StSci
- AISM, AoS, ANZS, Bern, Bka, CJS, CSSC, CSTM, CmpSt, CSDA, Envr, ISR, JASA, JAS, JCGS, JMA, JNS, JRSS-B, JSCS, JSPI, JTSA, Mtka, SJS, StCmp, Stats, StNee, StPap, SPL, StSin, Tech, Test
- StataJ
Undirected multi-edge
- AmS, BioJ, Bcs, Biost, EES, JABES, JBS, JRSS-A, JRSS-C, JSS, LDA, StMed, SMMR, StMod, StSci
- AISM, AoS, ANZS, Bern, Bka, CJS, CSSC, CSTM, CmpSt, CSDA, Envr, ISR, JASA, JAS, JCGS, JMA, JNS, JRSS-B, JSCS, JSPI, JTSA, Mtka, SJS, StCmp, Stats, StNee, StPap, SPL, StSin, Tech, Test
- StataJ
Undirected weighted
- AmS, BioJ, Bcs, Biost, EES, JABES, JBS, JRSS-A, JRSS-C, JSS, LDA, StMed, SMMR, StMod, StSci
- AISM, AoS, ANZS, Bern, Bka, CJS, CSSC, CSTM, CmpSt, CSDA, Envr, ISR, JASA, JAS, JCGS, JMA, JNS, JRSS-B, JSCS, JSPI, JTSA, Mtka, SJS, StCmp, Stats, StNee, StPap, SPL, StSin, Tech, Test
- StataJ
Visualisation
Here I am just trying out the ggraph package on the statistical journals datatset. The indicated clusters are those from agglomerative hierarchical clustering by Varin et al.
Asymmetric MDS

Symmetric MDS

Force-directed algorithm

Spring-based algorithm

Plotting communities
Following advice given in this StackOverflow answer we will aggregate communities into nodes representing each one (i.e. “super-journals”) and then plot them again to see if anything is worth looking at.
The visualisations above are definitely not scaleable to large networks (using R and ggraph, anyway), but the ones below can be applied to very large networks, if the number of clusters within them is only around 50–100 or so.
For now, we are only looking at the clustering given by Varin et al (2016).
Circular

Asymmetric MDS

Symmetric MDS

Force-directed

Spring-based

LS0tDQp0aXRsZTogIkNsdXN0ZXJpbmcgc3RhdGlzdGljcyBqb3VybmFscyINCmF1dGhvcjogIkRhdmlkIEEuIFNlbGJ5Ig0KZGF0ZTogImByIGZvcm1hdChTeXMuRGF0ZSgpLCAnJWUgJUIgJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9kb3dubG9hZDogeWVzDQotLS0NCg0KYGBge3Igc2V0dXAsIGluY2x1ZGUgPSBGQUxTRX0NCmtuaXRyOjpvcHRzX2NodW5rJHNldChlY2hvID0gRkFMU0UsIGNhY2hlID0gVFJVRSwgcmVzdWx0cyA9ICdhc2lzJywNCiAgICAgICAgICAgICAgICAgICAgICBkZXYuYXJncyA9IGxpc3QodHlwZSA9ICdjYWlybycpLA0KICAgICAgICAgICAgICAgICAgICAgIGZpZy53aWR0aCA9IDgsIGZpZy5oZWlnaHQgPSA4KQ0KYGBgDQoNClRoaXMgZG9jdW1lbnQgaG9wZXMgdG8gYmUgYSB1c2VmdWwgYmVuY2htYXJrIGZvciBhICJ0b3kiIGRhdGFzZXQsIG5hbWVseSB0aGUgbmV0d29yayBvZiA0NyBzdGF0aXN0aWNzIGpvdXJuYWxzIHN0dWRpZWQgaW4gdGhlIHBhcGVyIFZhcmluLCBDLiwgQ2F0dGVsYW4sIE0uIGFuZCBGaXJ0aCwgRC4gKDIwMTYpLCAiU3RhdGlzdGljYWwgbW9kZWxsaW5nIG9mIGNpdGF0aW9uIGV4Y2hhbmdlIGJldHdlZW4gc3RhdGlzdGljcyBqb3VybmFscyIuICpKLiBSLiBTdGF0LiBTb2MuIEEqLCAxNzk6IDHigJM2My4gW2RvaToxMC4xMTExL3Jzc2EuMTIxMjRdKGh0dHA6Ly9vbmxpbmVsaWJyYXJ5LndpbGV5LmNvbS9kb2kvMTAuMTExMS9yc3NhLjEyMTI0L2Fic3RyYWN0KS4NCg0KSXQgaXNuJ3QgYWx3YXlzIGNsZWFyIGhvdyB0aGUgdmFyaW91cyBpbXBsZW1lbnRhdGlvbnMgb2YgY29tbXVuaXR5IGRldGVjdGlvbiBhbGdvcml0aG1zIGhhbmRsZSBjYXNlcyBvZiBkaXJlY3RlZCBhbmQgdW5kaXJlY3RlZCBncmFwaHMgYW5kIHRoZSBkaWZmZXJlbmNlIGJldHdlZW4gd2VpZ2h0ZWQgZWRnZXMgb3IgbXVsdGlwbGUgdW53ZWlnaHRlZCBlZGdlcy4NClRoZXJlZm9yZSwgaW4gdGhpcyBkb2N1bWVudCB3ZSB3aWxsIHRyeSBlYWNoIG9mIHRoZSBmb3VyIGNvbWJpbmF0aW9ucyBqdXN0IHRvIHNlZSB3aGF0IGhhcHBlbnMuDQpXaGVyZSBgaWdyYXBoYCBhbGdvcml0aG1zIGFyZSBub3QgaW1wbGVtZW50ZWQgZm9yIHdlaWdodGVkIG9yIGRpcmVjdGVkIGdyYXBocywgdGhleSB3aWxsIHRocm93IGFuIGVycm9yLCB3aGljaCB3ZSBoYXZlIHJlcHJvZHVjZWQgdW5kZXIgdGhlIHJlc3BlY3RpdmUgdGFicy4NCkJld2FyZToganVzdCBiZWNhdXNlIHRoZSBhbGdvcml0aG0gZG9lcyBub3QgdGhyb3cgYW4gZXJyb3IgZG9lcyBub3QgbmVjZXNzYXJpbHkgbWVhbiB0aGF0IGRpcmVjdGlvbnMgb3Igd2VpZ2h0cyBhcmUgYWN0dWFsbHkgdGFrZW4gaW50byBhY2NvdW50Lg0KDQpTZWxmLWNpdGF0aW9ucyBoYXZlIG5vdCBiZWVuIGV4cGxpY2l0bHkgcmVtb3ZlZCBiZWZvcmUgcGVyZm9ybWluZyBhbnkgb2YgdGhlIHByb2NlZHVyZXMgYmVsb3cNCih0aG91Z2ggc29tZSBhbGdvcml0aG1zIG1heSBpbXBsaWNpdGx5IG9yIGV4cGxpY2l0bHkgaWdub3JlIHRoZW0pLg0KSSBtaWdodCB0cnkgcmVtb3Zpbmcgc2VsZi1jaXRhdGlvbnMgbGF0ZXIgdG8gc2VlIGlmIGl0IG1ha2VzIGFueSBub3RpY2VhYmxlIGRpZmZlcmVuY2UgdG8gdGhlIHJlc3VsdHMuDQoNCkFsc28gdG8gZG86IG5pY2UgbWluaW1hbCBwbG90cyBzbyB3ZSBkb24ndCBoYXZlIHRvIHJlYWQgbGlzdHMvdGFibGVzIGFsbCBkYXkuDQoqKlVwZGF0ZToqKiBbc2Nyb2xsIGRvd25dKCN2aXN1YWxpc2F0aW9uKSB0byBzZWUgc29tZSB2aXN1YWxpc2F0aW9ucy4NCg0KYGBge3IgdXRpbGl0aWVzLCByZXN1bHRzID0gJ21hcmt1cCd9DQpsaXN0aWZ5IDwtIGZ1bmN0aW9uKGNvbW11bml0aWVzLA0KICAgICAgICAgICAgICAgICAgICBtb2RlID0gJ2VudW1lcmF0ZScsDQogICAgICAgICAgICAgICAgICAgIHRpZ2h0bGlzdCA9IFRSVUUpIHsNCiAgIyBJbnB1dDogYSBjb21tdW5pdGllcyBvYmplY3Qgb3IgbWVtYmVyc2hpcCB2ZWN0b3INCiAgIyBPdXRwdXQ6IG1hcmtkb3duIGxpc3Qgb2YgdGhlIGdyb3Vwcw0KICBtb2RlIDwtIG1hdGNoLmFyZyhtb2RlLCBjKCdpdGVtaXNlJywgJ2VudW1lcmF0ZScpKQ0KICBpZiAoJ2NvbW11bml0aWVzJyAlaW4lIGNsYXNzKGNvbW11bml0aWVzKSkNCiAgICBncm91cHNsaXN0IDwtIGdyb3Vwcyhjb21tdW5pdGllcykNCiAgZWxzZQ0KICAgIGdyb3Vwc2xpc3QgPC0gc3BsaXQobmFtZXMoY29tbXVuaXRpZXMpLCBjb21tdW5pdGllcykNCiAgb3V0Zm4gPC0gZnVuY3Rpb24oZ3JwKQ0KICAgIHBhc3RlKHN3aXRjaChtb2RlLCBpdGVtaXNlID0gJy0nLCBlbnVtZXJhdGUgPSAnMS4nKSwNCiAgICAgICAgICBwYXN0ZShncnAsIGNvbGxhcHNlID0gJywgJykpDQogIG91dGxpc3QgPC0gdmFwcGx5KGdyb3Vwc2xpc3QsIG91dGZuLCBjaGFyYWN0ZXIoMSkpDQogIHdyaXRlTGluZXMob3V0bGlzdCwgc2VwID0gaWZlbHNlKHRpZ2h0bGlzdCwgJ1xuJywgJ1xuXG4nKSkNCn0NCg0KbWFrZV90aXRsZSA8LSAgZnVuY3Rpb24oZ3JhcGgpIHsNCiAgc3dpdGNoKGdyYXBoLA0KICAgICAgICAgZGlyZWN0ZWRfbXVsdGkgPSAnRGlyZWN0ZWQgbXVsdGktZWRnZScsDQogICAgICAgICBkaXJlY3RlZF93ZWlnaHRlZCA9ICdEaXJlY3RlZCB3ZWlnaHRlZCcsDQogICAgICAgICB1bmRpcmVjdGVkX211bHRpID0gJ1VuZGlyZWN0ZWQgbXVsdGktZWRnZScsDQogICAgICAgICB1bmRpcmVjdGVkX3dlaWdodGVkID0gJ1VuZGlyZWN0ZWQgd2VpZ2h0ZWQnLA0KICAgICAgICAgZ19zY2FsZSA9ICdEaXJlY3RlZCwgc2NhbGVkIHdlaWdodGVkJywNCiAgICAgICAgIHN0b3AoJ0dyYXBoIG5vdCB1bi9kaXJlY3RlZCBvciB1bi93ZWlnaHRlZCcpKSAtPg0KICAgIG91dHB1dA0KICB3cml0ZUxpbmVzKHBhc3RlKCdcbiMjIyMnLCBvdXRwdXQpKQ0KfQ0KDQp0cnlfY2x1c3RlcmluZyA8LSBmdW5jdGlvbihmLCBncmFwaCwgLi4uKSB7DQogIHNldC5zZWVkKDIwMTcpICMgZm9yIGNvbnNpc3RlbmN5IGJldHdlZW4gZ3JhcGhzDQogIHRyeUNhdGNoKHsNCiAgICAgIG1ha2VfdGl0bGUoZGVwYXJzZShzdWJzdGl0dXRlKGdyYXBoKSkpDQogICAgICBsaXN0aWZ5KGYoZ3JhcGgsIC4uLikpDQogICAgfSwNCiAgICBlcnJvciA9IGZ1bmN0aW9uKGNvbmQpIHsNCiAgICAgIGNhdCgnPGRpdiBjbGFzcz0iYWxlcnQgYWxlcnQtZGFuZ2VyIj4nLA0KICAgICAgICAgICc8c3Ryb25nPu+4j0xvb2tzIGxpa2UgYW4gZXJyb3IhIEhlcmUgaXMgdGhlIG1lc3NhZ2U6PC9zdHJvbmc+PGJyIC8+JywNCiAgICAgICAgICBjb25kJG1lc3NhZ2UsDQogICAgICAgICAgJzwvZGl2PicsDQogICAgICAgICAgc2VwID0gJ1xuJykNCiAgICB9DQogICkNCn0NCmBgYA0KDQpgYGB7ciBtYWtlX2dyYXBoc30NCnN1cHByZXNzUGFja2FnZVN0YXJ0dXBNZXNzYWdlcyhsaWJyYXJ5KGlncmFwaCkpDQpDIDwtIHNjcm9vZ2U6OmNpdGF0aW9ucw0KIyBCZSBjYXJlZnVsISBpbiBpZ3JhcGgsIGNpdGF0aW9ucyBnbyBmcm9tIHJvd3MtPmNvbHVtbnMuIFNvIHdlIG5lZWQgdG8gdXNlIHQoKQ0KZGlyZWN0ZWRfbXVsdGkgPC0gZ3JhcGhfZnJvbV9hZGphY2VuY3lfbWF0cml4KHQoQykpDQpkaXJlY3RlZF93ZWlnaHRlZCA8LSBncmFwaF9mcm9tX2FkamFjZW5jeV9tYXRyaXgodChDKSwgd2VpZ2h0ZWQgPSBUUlVFKQ0KdW5kaXJlY3RlZF9tdWx0aSA8LSBncmFwaF9mcm9tX2FkamFjZW5jeV9tYXRyaXgoQywgbW9kZSA9ICdwbHVzJykNCnVuZGlyZWN0ZWRfd2VpZ2h0ZWQgPC0gZ3JhcGhfZnJvbV9hZGphY2VuY3lfbWF0cml4KEMsIG1vZGUgPSAncGx1cycsIHdlaWdodGVkID0gVFJVRSkNCmBgYA0KDQojIyMgSW5mb21hcCBhbGdvcml0aG0gey50YWJzZXR9DQoNCmBgYHtyIGluZm9tYXB9DQp0cnlfY2x1c3RlcmluZyhjbHVzdGVyX2luZm9tYXAsIGRpcmVjdGVkX211bHRpKQ0KdHJ5X2NsdXN0ZXJpbmcoY2x1c3Rlcl9pbmZvbWFwLCBkaXJlY3RlZF93ZWlnaHRlZCkNCnRyeV9jbHVzdGVyaW5nKGNsdXN0ZXJfaW5mb21hcCwgdW5kaXJlY3RlZF9tdWx0aSkNCnRyeV9jbHVzdGVyaW5nKGNsdXN0ZXJfaW5mb21hcCwgdW5kaXJlY3RlZF93ZWlnaHRlZCkNCmBgYA0KDQojIyMgQWdnbG9tZXJhdGl2ZSBoaWVyYXJjaGljYWwgY2x1c3RlcmluZyB7LnRhYnNldH0NCg0KYGBge3IsIGhjbHVzdH0NCndyaXRlTGluZXMoJ1xuIyMjIyBEaXJlY3RlZCwgY29tcGxldGUtbGlua2FnZScpDQp0b3RhbEMgPC0gQyArIHQoQykgIyBWYXJpbiBldCBhbCBzZWN0aW9uIDMNCmRpYWcodG90YWxDKSA8LSBkaWFnKEMpDQpEX2RpciA8LSBhcy5kaXN0KDEgLSBjb3IodChDKSkpICMgYXNzdW1pbmcgd2UgY2FyZSBhYm91dCB3aG8gdGhleSBjaXRlLCBub3Qgd2hvIGNpdGVzIHRoZW0NCmhjbHVzdF9kaXIgPC0gaGNsdXN0KERfZGlyLCBtZXRob2QgPSAnY29tcGxldGUnKQ0KaGNsdXN0X2RpciA8LSBjdXRyZWUoaGNsdXN0X2RpciwgaCA9IDAuNikNCmxpc3RpZnkoaGNsdXN0X2RpcikNCg0Kd3JpdGVMaW5lcygnXG4jIyMjIFVuZGlyZWN0ZWQsIGNvbXBsZXRlLWxpbmthZ2UnKSAjIFNob3VsZCBtYXRjaCBhcHByb2FjaCBvZiBWYXJpbiBldCBhbC4gKDIwMTYpDQpEX3VkIDwtIGFzLmRpc3QoMSAtIGNvcih0b3RhbEMpKQ0KaGNsdXN0X3VkIDwtIGhjbHVzdChEX3VkLCBtZXRob2QgPSAnY29tcGxldGUnKQ0KaGNsdXN0X3VkIDwtIGN1dHJlZShoY2x1c3RfdWQsIGggPSAwLjYpDQpsaXN0aWZ5KGhjbHVzdF91ZCkNCmBgYA0KDQoqSGllcmFyY2hpY2FsIGNsdXN0ZXJpbmcgd2l0aCBjb21wbGV0ZSBsaW5rYWdlLCBhcHBsaWVkIHRvIHRoZSB1bmRpcmVjdGVkIFBlYXJzb24gY29ycmVsYXRpb24gbWF0cml4LCBzaG91bGQgZXhhY3RseSByZXByb2R1Y2UgdGhlIHJlc3VsdHMgb2YgVmFyaW4gZXQgYWwgKDIwMTYpLioNCg0KIyMjIEVkZ2UgYmV0d2Vlbm5lc3Mgey50YWJzZXR9DQoNCmBgYHtyIGJldHdlZW5uZXNzLCBjYWNoZSA9IFRSVUV9DQojd2FybmluZygnVGhlIGVkZ2UtYmV0d2VlbmVzcyBhbGdvcml0aG0gaXMgdmVyeSBzbG93IScpDQp0cnlfY2x1c3RlcmluZyhjbHVzdGVyX2VkZ2VfYmV0d2Vlbm5lc3MsIGRpcmVjdGVkX211bHRpKQ0KdHJ5X2NsdXN0ZXJpbmcoY2x1c3Rlcl9lZGdlX2JldHdlZW5uZXNzLCBkaXJlY3RlZF93ZWlnaHRlZCkNCnRyeV9jbHVzdGVyaW5nKGNsdXN0ZXJfZWRnZV9iZXR3ZWVubmVzcywgdW5kaXJlY3RlZF9tdWx0aSkNCnRyeV9jbHVzdGVyaW5nKGNsdXN0ZXJfZWRnZV9iZXR3ZWVubmVzcywgdW5kaXJlY3RlZF93ZWlnaHRlZCkNCmBgYA0KDQojIyMgTW9kdWxhcml0eSBvcHRpbWlzYXRpb246IGZhc3QgYW5kIGdyZWVkeSB7LnRhYnNldH0NCg0KYGBge3IgZmFzdF9ncmVlZHl9DQp0cnlfY2x1c3RlcmluZyhjbHVzdGVyX2Zhc3RfZ3JlZWR5LCBkaXJlY3RlZF9tdWx0aSkNCnRyeV9jbHVzdGVyaW5nKGNsdXN0ZXJfZmFzdF9ncmVlZHksIGRpcmVjdGVkX3dlaWdodGVkKQ0KdHJ5X2NsdXN0ZXJpbmcoY2x1c3Rlcl9mYXN0X2dyZWVkeSwgdW5kaXJlY3RlZF9tdWx0aSkNCnRyeV9jbHVzdGVyaW5nKGNsdXN0ZXJfZmFzdF9ncmVlZHksIHVuZGlyZWN0ZWRfd2VpZ2h0ZWQpDQpgYGANCg0KIyMjIE1vZHVsYXJpdHkgb3B0aW1pc2F0aW9uOiBMb3V2YWluIG1ldGhvZCAoQmxvbmRlbCBldCBhbCkgey50YWJzZXR9DQoNCmBgYHtyIGxvdXZhaW59DQp0cnlfY2x1c3RlcmluZyhjbHVzdGVyX2xvdXZhaW4sIGRpcmVjdGVkX211bHRpKQ0KdHJ5X2NsdXN0ZXJpbmcoY2x1c3Rlcl9sb3V2YWluLCBkaXJlY3RlZF93ZWlnaHRlZCkNCnRyeV9jbHVzdGVyaW5nKGNsdXN0ZXJfbG91dmFpbiwgdW5kaXJlY3RlZF9tdWx0aSkNCnRyeV9jbHVzdGVyaW5nKGNsdXN0ZXJfbG91dmFpbiwgdW5kaXJlY3RlZF93ZWlnaHRlZCkNCmBgYA0KDQojIyMgU3BpbmdsYXNzIG1ldGhvZCB7LnRhYnNldH0NCg0KYGBge3Igc3BpbmdsYXNzfQ0KdHJ5X2NsdXN0ZXJpbmcoY2x1c3Rlcl9zcGluZ2xhc3MsIGRpcmVjdGVkX211bHRpKQ0KdHJ5X2NsdXN0ZXJpbmcoY2x1c3Rlcl9zcGluZ2xhc3MsIGRpcmVjdGVkX3dlaWdodGVkKQ0KdHJ5X2NsdXN0ZXJpbmcoY2x1c3Rlcl9zcGluZ2xhc3MsIHVuZGlyZWN0ZWRfbXVsdGkpDQp0cnlfY2x1c3RlcmluZyhjbHVzdGVyX3NwaW5nbGFzcywgdW5kaXJlY3RlZF93ZWlnaHRlZCkNCmBgYA0KDQojIyMgUmFuZG9tIHdhbGtzICh3YWxrdHJhcCkgey50YWJzZXR9DQoNCkJhc2VkIG9uIHJhbmRvbSB3YWxrcyBvZiA2IHN0ZXBzLg0KDQpTZWUgUGFzY2FsIFBvbnMsIE1hdHRoaWV1IExhdGFweTogQ29tcHV0aW5nIGNvbW11bml0aWVzIGluIGxhcmdlIG5ldHdvcmtzIHVzaW5nIHJhbmRvbSB3YWxrcywgaHR0cDovL2FyeGl2Lm9yZy9hYnMvcGh5c2ljcy8wNTEyMTA2DQoNCmBgYHtyIHdhbGt0cmFwfQ0KdHJ5X2NsdXN0ZXJpbmcoY2x1c3Rlcl93YWxrdHJhcCwgZGlyZWN0ZWRfbXVsdGksIHN0ZXBzID0gNikNCnRyeV9jbHVzdGVyaW5nKGNsdXN0ZXJfd2Fsa3RyYXAsIGRpcmVjdGVkX3dlaWdodGVkLCBzdGVwcyA9IDYpDQp0cnlfY2x1c3RlcmluZyhjbHVzdGVyX3dhbGt0cmFwLCB1bmRpcmVjdGVkX211bHRpLCBzdGVwcyA9IDYpDQp0cnlfY2x1c3RlcmluZyhjbHVzdGVyX3dhbGt0cmFwLCB1bmRpcmVjdGVkX3dlaWdodGVkLCBzdGVwcyA9IDYpDQpgYGANCg0KIyMgVmlzdWFsaXNhdGlvbiB7LnRhYnNldH0NCg0KSGVyZSBJIGFtIGp1c3QgdHJ5aW5nIG91dCB0aGUgYGdncmFwaGAgcGFja2FnZSBvbiB0aGUgc3RhdGlzdGljYWwgam91cm5hbHMgZGF0YXRzZXQuDQpUaGUgaW5kaWNhdGVkIGNsdXN0ZXJzIGFyZSB0aG9zZSBmcm9tIFthZ2dsb21lcmF0aXZlIGhpZXJhcmNoaWNhbCBjbHVzdGVyaW5nIGJ5IFZhcmluIGV0IGFsXVthZ2ddLg0KDQpbYWdnXTogI2FnZ2xvbWVyYXRpdmUtaGllcmFyY2hpY2FsLWNsdXN0ZXJpbmcNCg0KYGBge3IgZm9udHNfYW5kX3N0dWZmfQ0KZXh0cmFmb250Ojpsb2FkZm9udHMocXVpZXQgPSBUUlVFKQ0KaWYoISgnQXJpYWwgTmFycm93JyAlaW4lIGV4dHJhZm9udDo6Zm9udHMoKSkpDQogIGNhdCgnKldhcm5pbmcqOiBBcmlhbCBOYXJyb3cgd2FzIG5vdCBsb2FkZWQnKQ0KYGBgDQoNCiMjIyBBc3ltbWV0cmljIE1EUw0KDQpgYGB7ciBtZHN9DQpnZzQ3IDwtIGdyYXBoX2Zyb21fYWRqYWNlbmN5X21hdHJpeCh0KHNjcm9vZ2U6OmNpdGF0aW9ucykpDQpnZ3Rlc3QgPC0gc2ltcGxpZnkoZ2c0NywgcmVtb3ZlLmxvb3BzID0gVFJVRSwgcmVtb3ZlLm11bHRpcGxlID0gRkFMU0UpDQpWKGdndGVzdCkkSW5kZWdyZWUgPC0gZGVncmVlKGdndGVzdCwgbW9kZSA9ICdpbicpDQpWKGdndGVzdCkkT3V0ZGdyZWUgPC0gZGVncmVlKGdndGVzdCwgbW9kZSA9ICdvdXQnKQ0KVihnZ3Rlc3QpJFBhZ2VSYW5rIDwtIHBhZ2UucmFuayhnZ3Rlc3QpJHZlY3Rvcg0KVihnZ3Rlc3QpJGNsdXN0ZXIgPC0gaGNsdXN0X3VkDQoNCmxpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoZ2dyYXBoKQ0KDQptZHNfbGF5b3V0IDwtIGNyZWF0ZV9sYXlvdXQoZ2d0ZXN0LCBsYXlvdXQgPSAnaWdyYXBoJywgYWxnb3JpdGhtID0gJ21kcycsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzdCA9IDEgLSBjb3IoQywgbWV0aG9kID0gJ3BlYXJzb24nKSkNCmdncmFwaChtZHNfbGF5b3V0KSArDQogIGdlb21fZWRnZV9mYW4wKGFscGhhID0gMC4wMSwNCiAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgIGNvbG91ciA9ICdzdGVlbGJsdWUnKSArDQogIGdlb21fbm9kZV9wb2ludChhZXMoc2l6ZSA9IFBhZ2VSYW5rLCBjb2xvdXIgPSBhcy5mYWN0b3IoY2x1c3RlcikpKSArDQogIHNjYWxlX2NvbG91cl9icmV3ZXIoJ0NsdXN0ZXInLCB0eXBlID0gJ3F1YWwnLCBwYWxldHRlID0gJ1NldDEnKSArDQogIGNvb3JkX2ZpeGVkKCkgKw0KICBnZ3RpdGxlKCdNdWx0aWRpbWVuc2lvbmFsIFNjYWxpbmcgb2YgUGVhcnNvbiBkaXN0YW5jZXMnLA0KICAgICAgICAgIHN1YnRpdGxlID0gJ0FzeW1tZXRyaWMnKSArDQogIHRoZW1lX2dyYXBoKCkNCmBgYA0KDQojIyMgU3ltbWV0cmljIE1EUw0KDQpgYGB7ciBtZHMyfQ0KbWRzX2xheW91dDIgPC0gY3JlYXRlX2xheW91dChnZ3Rlc3QsIGxheW91dCA9ICdpZ3JhcGgnLCBhbGdvcml0aG0gPSAnbWRzJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzdCA9IDEgLSBjb3IodG90YWxDLCBtZXRob2QgPSAncGVhcnNvbicpKQ0KZ2dyYXBoKG1kc19sYXlvdXQyKSArDQogIGdlb21fZWRnZV9mYW4wKGFscGhhID0gMC4wMSwNCiAgICAgICAgICAgICAgICBzaG93LmxlZ2VuZCA9IEZBTFNFLA0KICAgICAgICAgICAgICAgIGNvbG91ciA9ICdzdGVlbGJsdWUnKSArDQogIGdlb21fbm9kZV9wb2ludChhZXMoc2l6ZSA9IFBhZ2VSYW5rLCBjb2xvdXIgPSBhcy5mYWN0b3IoY2x1c3RlcikpKSArDQogIHNjYWxlX2NvbG91cl9icmV3ZXIoJ0NsdXN0ZXInLCB0eXBlID0gJ3F1YWwnLCBwYWxldHRlID0gJ1NldDEnKSArDQogIGNvb3JkX2ZpeGVkKCkgKw0KICBnZ3RpdGxlKCdNdWx0aWRpbWVuc2lvbmFsIFNjYWxpbmcgb2YgUGVhcnNvbiBkaXN0YW5jZXMnLA0KICAgICAgICAgIHN1YnRpdGxlID0gJ1N5bW1ldHJpc2VkJykgKw0KICB0aGVtZV9ncmFwaCgpDQpgYGANCg0KIyMjIEZvcmNlLWRpcmVjdGVkIGFsZ29yaXRobQ0KDQpgYGB7ciBmcn0NCmdncmFwaChnZ3Rlc3QsIGxheW91dCA9ICdmcicpICsNCiAgZ2VvbV9lZGdlX2ZhbjAoYWxwaGEgPSAwLjAxLA0KICAgICAgICAgICAgICAgIHNob3cubGVnZW5kID0gRkFMU0UsDQogICAgICAgICAgICAgICAgY29sb3VyID0gJ3N0ZWVsYmx1ZScpICsNCiAgZ2VvbV9ub2RlX3BvaW50KGFlcyhzaXplID0gUGFnZVJhbmssIGNvbG91ciA9IGFzLmZhY3RvcihjbHVzdGVyKSkpICsNCiAgc2NhbGVfY29sb3VyX2JyZXdlcignQ2x1c3RlcicsIHR5cGUgPSAncXVhbCcsIHBhbGV0dGUgPSAnU2V0MScpICsNCiAgY29vcmRfZml4ZWQoKSArDQogIGdndGl0bGUoJ0ZydWNodGVybWFuIGFuZCBSZWluZ29sZCcpICsNCiAgdGhlbWVfZ3JhcGgoKQ0KYGBgDQoNCiMjIyBTcHJpbmctYmFzZWQgYWxnb3JpdGhtDQoNCmBgYHtyIGtrfQ0KZ2dyYXBoKGdndGVzdCwgbGF5b3V0ID0gJ2trJykgKw0KICBnZW9tX2VkZ2VfZmFuMChhbHBoYSA9IDAuMDEsDQogICAgICAgICAgICAgICAgc2hvdy5sZWdlbmQgPSBGQUxTRSwNCiAgICAgICAgICAgICAgICBjb2xvdXIgPSAnc3RlZWxibHVlJykgKw0KICBnZW9tX25vZGVfcG9pbnQoYWVzKHNpemUgPSBQYWdlUmFuaywgY29sb3VyID0gYXMuZmFjdG9yKGNsdXN0ZXIpKSkgKw0KICBzY2FsZV9jb2xvdXJfYnJld2VyKCdDbHVzdGVyJywgdHlwZSA9ICdxdWFsJywgcGFsZXR0ZSA9ICdTZXQxJykgKw0KICBjb29yZF9maXhlZCgpICsNCiAgZ2d0aXRsZSgnS2FtYWRhIGFuZCBLYXdhaScpICsNCiAgdGhlbWVfZ3JhcGgoKQ0KYGBgDQoNCiMjIFBsb3R0aW5nIGNvbW11bml0aWVzIHsudGFic2V0fQ0KDQpGb2xsb3dpbmcgYWR2aWNlIGdpdmVuIGluIFt0aGlzIFN0YWNrT3ZlcmZsb3cgYW5zd2VyXShodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjA4NDU0MzEpIHdlIHdpbGwgYWdncmVnYXRlIGNvbW11bml0aWVzIGludG8gbm9kZXMgcmVwcmVzZW50aW5nIGVhY2ggb25lIChpLmUuICJzdXBlci1qb3VybmFscyIpIGFuZCB0aGVuIHBsb3QgdGhlbSBhZ2FpbiB0byBzZWUgaWYgYW55dGhpbmcgaXMgd29ydGggbG9va2luZyBhdC4NCg0KVGhlIHZpc3VhbGlzYXRpb25zIGFib3ZlIGFyZSBkZWZpbml0ZWx5IG5vdCBzY2FsZWFibGUgdG8gbGFyZ2UgbmV0d29ya3MgKHVzaW5nIFIgYW5kIGBnZ3JhcGhgLCBhbnl3YXkpLCBidXQgdGhlIG9uZXMgYmVsb3cgY2FuIGJlIGFwcGxpZWQgdG8gdmVyeSBsYXJnZSBuZXR3b3JrcywgaWYgdGhlIG51bWJlciBvZiBjbHVzdGVycyB3aXRoaW4gdGhlbSBpcyBvbmx5IGFyb3VuZCA1MC0tMTAwIG9yIHNvLg0KDQpGb3Igbm93LCB3ZSBhcmUgb25seSBsb29raW5nIGF0IHRoZSBbY2x1c3RlcmluZyBnaXZlbiBieSBWYXJpbiBldCBhbCAoMjAxNildW2FnZ10uDQoNCmBgYHtyIGNvbW11bml0eV9ub2Rlc30NCiMgU2VlIHRpcHMgaGVyZTogaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzIwODQ1NDMxDQpWKGdnNDcpJG1lbWJlcnMgPC0gMQ0KVihnZzQ3KSRjbHVzdGVyIDwtIGFzLmZhY3RvcihoY2x1c3RfdWQpDQpFKGdnNDcpJGNvdW50IDwtIDENCg0KIyBDb250cmFjdCBjb21tdW5pdGllcyBpbnRvIHZlcnRpY2VzDQpncmFwaF9oY2x1c3QgPC0gY29udHJhY3QudmVydGljZXMoZ3JhcGggPSBnZzQ3LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hcHBpbmcgPSBoY2x1c3RfdWQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdmVydGV4LmF0dHIuY29tYiA9IGxpc3QoDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtZW1iZXJzID0gJ3N1bScsICMgY291bnQgbWVtYmVycw0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2x1c3RlciA9ICdmaXJzdCcsICMgY2x1c3RlciBJRA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2lnbm9yZScgIyBkcm9wIG90aGVyIGF0dHJpYnV0ZXMNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICApKQ0KIyBDb2xsYXBzZSBtdWx0aXBsZSBlZGdlcyAoYW5kIHJlbW92ZSBzZWxmLWNpdGF0aW9ucyB3aGlsZSB3ZSdyZSBhdCBpdCkNCiMgZ3JhcGhfaGNsdXN0IDwtIHNpbXBsaWZ5KGdyYXBoX2hjbHVzdCwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgIHJlbW92ZS5sb29wcyA9IEZBTFNFLA0KIyAgICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlLm11bHRpcGxlID0gVFJVRSwNCiMgICAgICAgICAgICAgICAgICAgICAgICAgIGVkZ2UuYXR0ci5jb21iID0gbGlzdCgNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgY291bnQgPSAnc3VtJywNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2lnbm9yZScNCiMgICAgICAgICAgICAgICAgICAgICAgICAgICkpDQpgYGANCg0KIyMjIENpcmN1bGFyDQoNCmBgYHtyIGNvbW1fcGxvdH0NCiMgTm90IHF1aXRlIGNvbXBhcmFibGUgdG8gZWFybGllciBNRFMgeWV0DQpnZ3JhcGgoZ3JhcGhfaGNsdXN0LCBsYXlvdXQgPSAnY2lyY2xlJykgKw0KICBnZW9tX2VkZ2VfZmFuMChhbHBoYSA9IC4wMSwgY29sb3VyID0gJ3N0ZWVsYmx1ZScpICsNCiAgZ2VvbV9ub2RlX3BvaW50KGFlcyhzaXplID0gbWVtYmVycywgY29sb3VyID0gYXMuZmFjdG9yKGNsdXN0ZXIpKSkgKw0KICBzY2FsZV9jb2xvdXJfYnJld2VyKCdDbHVzdGVyJywgdHlwZSA9ICdxdWFsJywgcGFsZXR0ZSA9ICdTZXQxJykgKw0KICBjb29yZF9maXhlZCgpICsNCiAgZ2d0aXRsZSgnQ2l0YXRpb25zIGJldHdlZW4gY29tbXVuaXRpZXMnLA0KICAgICAgICAgIHN1YnRpdGxlID0gJ0NpcmN1bGFyIGxheW91dCcpICsNCiAgdGhlbWVfZ3JhcGgoKQ0KYGBgDQoNCiMjIyBBc3ltbWV0cmljIE1EUw0KDQpgYGB7ciBjb21tX21kc30NCiMgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9hLzI3NTEyOTg5DQojIE1ha2Ugc3VwZXItam91cm5hbCBjcm9zcy1jaXRhdGlvbiBtYXRyaXgNCg0KQ19oYyA8LSBhcy5kYXRhLmZyYW1lLnRhYmxlKEMpDQpsZXZlbHMoQ19oYyRjaXRlZCkgPC0gbGV2ZWxzKENfaGMkY2l0aW5nKSA8LSBzcGxpdChuYW1lcyhoY2x1c3RfdWQpLCBoY2x1c3RfdWQpDQpDX2hjIDwtIHh0YWJzKEZyZXEgfiBjaXRlZCArIGNpdGluZywgQ19oYykNCg0KbWRzX2xheW91dF9jb21tIDwtIGNyZWF0ZV9sYXlvdXQoZ3JhcGhfaGNsdXN0LA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGF5b3V0ID0gJ2lncmFwaCcsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhbGdvcml0aG0gPSAnbWRzJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc3QgPSAxIC0gY29yKHQoQ19oYykpKQ0KDQpnZ3JhcGgobWRzX2xheW91dF9jb21tKSArDQogIGdlb21fZWRnZV9mYW4wKGFscGhhID0gLjAxLCBjb2xvdXIgPSAnc3RlZWxibHVlJykgKw0KICBnZW9tX25vZGVfcG9pbnQoYWVzKHNpemUgPSBtZW1iZXJzLCBjb2xvdXIgPSBhcy5mYWN0b3IoY2x1c3RlcikpKSArDQogIHNjYWxlX2NvbG91cl9icmV3ZXIoJ0NsdXN0ZXInLCB0eXBlID0gJ3F1YWwnLCBwYWxldHRlID0gJ1NldDEnKSArDQogIGNvb3JkX2ZpeGVkKCkgKw0KICBnZ3RpdGxlKCdDaXRhdGlvbnMgYmV0d2VlbiBjb21tdW5pdGllcycsDQogICAgICAgICAgc3VidGl0bGUgPSAnQXN5bW1ldHJpYyBtdWx0aWRpbWVuc2lvbmFsIHNjYWxpbmcnKSArDQogIHRoZW1lX2dyYXBoKCkNCmBgYA0KDQojIyMgU3ltbWV0cmljIE1EUw0KDQpgYGB7ciBjb21tX21kc19zeW19DQp0b3RhbENfaGMgPC0gQ19oYyArIHQoQ19oYykgLSBkaWFnKGRpYWcoQ19oYykpDQoNCm1kc19sYXlvdXRfY29tbTIgPC0gY3JlYXRlX2xheW91dChncmFwaF9oY2x1c3QsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsYXlvdXQgPSAnaWdyYXBoJywNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFsZ29yaXRobSA9ICdtZHMnLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzdCA9IDEgLSBjb3IodG90YWxDX2hjKSkNCg0KZ2dyYXBoKG1kc19sYXlvdXRfY29tbTIpICsNCiAgZ2VvbV9lZGdlX2ZhbjAoYWxwaGEgPSAuMDEsIGNvbG91ciA9ICdzdGVlbGJsdWUnKSArDQogIGdlb21fbm9kZV9wb2ludChhZXMoc2l6ZSA9IG1lbWJlcnMsIGNvbG91ciA9IGFzLmZhY3RvcihjbHVzdGVyKSkpICsNCiAgc2NhbGVfY29sb3VyX2JyZXdlcignQ2x1c3RlcicsIHR5cGUgPSAncXVhbCcsIHBhbGV0dGUgPSAnU2V0MScpICsNCiAgY29vcmRfZml4ZWQoKSArDQogIGdndGl0bGUoJ0NpdGF0aW9ucyBiZXR3ZWVuIGNvbW11bml0aWVzJywNCiAgICAgICAgICBzdWJ0aXRsZSA9ICdTeW1tZXRyaWMgbXVsdGlkaW1lbnNpb25hbCBzY2FsaW5nJykgKw0KICB0aGVtZV9ncmFwaCgpDQpgYGANCg0KIyMjIEZvcmNlLWRpcmVjdGVkDQoNCmBgYHtyIGNvbW1fZnJ9DQpnZ3JhcGgoZ3JhcGhfaGNsdXN0LCBsYXlvdXQgPSAnZnInKSArDQogIGdlb21fZWRnZV9mYW4wKGFscGhhID0gLjAxLCBjb2xvdXIgPSAnc3RlZWxibHVlJykgKw0KICBnZW9tX25vZGVfcG9pbnQoYWVzKHNpemUgPSBtZW1iZXJzLCBjb2xvdXIgPSBhcy5mYWN0b3IoY2x1c3RlcikpKSArDQogIHNjYWxlX2NvbG91cl9icmV3ZXIoJ0NsdXN0ZXInLCB0eXBlID0gJ3F1YWwnLCBwYWxldHRlID0gJ1NldDEnKSArDQogIGNvb3JkX2ZpeGVkKCkgKw0KICBnZ3RpdGxlKCdDaXRhdGlvbnMgYmV0d2VlbiBjb21tdW5pdGllcycsDQogICAgICAgICAgc3VidGl0bGUgPSAnRnJ1Y2h0ZXJtYW4gYW5kIFJlaW5nb2xkIGxheW91dCcpICsNCiAgdGhlbWVfZ3JhcGgoKQ0KYGBgDQoNCiMjIyBTcHJpbmctYmFzZWQNCg0KYGBge3IgY29tbV9ra30NCmdncmFwaChncmFwaF9oY2x1c3QsIGxheW91dCA9ICdraycpICsNCiAgZ2VvbV9lZGdlX2ZhbjAoYWxwaGEgPSAuMDEsIGNvbG91ciA9ICdzdGVlbGJsdWUnKSArDQogIGdlb21fbm9kZV9wb2ludChhZXMoc2l6ZSA9IG1lbWJlcnMsIGNvbG91ciA9IGFzLmZhY3RvcihjbHVzdGVyKSkpICsNCiAgc2NhbGVfY29sb3VyX2JyZXdlcignQ2x1c3RlcicsIHR5cGUgPSAncXVhbCcsIHBhbGV0dGUgPSAnU2V0MScpICsNCiAgY29vcmRfZml4ZWQoKSArDQogIGdndGl0bGUoJ0NpdGF0aW9ucyBiZXR3ZWVuIGNvbW11bml0aWVzJywNCiAgICAgICAgICBzdWJ0aXRsZSA9ICdLYW1hZGEgYW5kIEthd2FpIGxheW91dCcpICsNCiAgdGhlbWVfZ3JhcGgoKQ0KYGBgDQo=