IyEgL3Vzci9iaW4vZW52IHB5dGhvbjMKIyAtKi0gY29kaW5nOiBpc28tODg1OS0xIC0qLQojIE9yaWdpbmFsbHkgd3JpdHRlbiBieSBCYXJyeSBXYXJzYXcgPGJhcnJ5QHB5dGhvbi5vcmc+CiMKIyBNaW5pbWFsbHkgcGF0Y2hlZCB0byBtYWtlIGl0IGV2ZW4gbW9yZSB4Z2V0dGV4dCBjb21wYXRpYmxlCiMgYnkgUGV0ZXIgRnVuayA8cGZAYXJ0Y29tLWdtYmguZGU+CiMKIyAyMDAyLTExLTIyIEr8cmdlbiBIZXJtYW5uIDxqaEB3ZWIuZGU+CiMgQWRkZWQgY2hlY2tzIHRoYXQgXygpIG9ubHkgY29udGFpbnMgc3RyaW5nIGxpdGVyYWxzLCBhbmQKIyBjb21tYW5kIGxpbmUgYXJncyBhcmUgcmVzb2x2ZWQgdG8gbW9kdWxlIGxpc3RzLCBpLmUuIHlvdQojIGNhbiBub3cgcGFzcyBhIGZpbGVuYW1lLCBhIG1vZHVsZSBvciBwYWNrYWdlIG5hbWUsIG9yIGEKIyBkaXJlY3RvcnkgKGluY2x1ZGluZyBnbG9iYmluZyBjaGFycywgaW1wb3J0YW50IGZvciBXaW4zMikuCiMgTWFkZSBkb2NzdHJpbmcgZml0IGluIDgwIGNoYXJzIHdpZGUgZGlzcGxheXMgdXNpbmcgcHlkb2MuCiMKCiMgZm9yIHNlbGZ0ZXN0aW5nCnRyeToKICAgIGltcG9ydCBmaW50bAogICAgXyA9IGZpbnRsLmdldHRleHQKZXhjZXB0IEltcG9ydEVycm9yOgogICAgXyA9IGxhbWJkYSBzOiBzCgpfX2RvY19fID0gXygiIiJweWdldHRleHQgLS0gUHl0aG9uIGVxdWl2YWxlbnQgb2YgeGdldHRleHQoMSkKCk1hbnkgc3lzdGVtcyAoU29sYXJpcywgTGludXgsIEdudSkgcHJvdmlkZSBleHRlbnNpdmUgdG9vbHMgdGhhdCBlYXNlIHRoZQppbnRlcm5hdGlvbmFsaXphdGlvbiBvZiBDIHByb2dyYW1zLiBNb3N0IG9mIHRoZXNlIHRvb2xzIGFyZSBpbmRlcGVuZGVudCBvZgp0aGUgcHJvZ3JhbW1pbmcgbGFuZ3VhZ2UgYW5kIGNhbiBiZSB1c2VkIGZyb20gd2l0aGluIFB5dGhvbiBwcm9ncmFtcy4KTWFydGluIHZvbiBMb2V3aXMnIHdvcmtbMV0gaGVscHMgY29uc2lkZXJhYmx5IGluIHRoaXMgcmVnYXJkLgoKVGhlcmUncyBvbmUgcHJvYmxlbSB0aG91Z2g7IHhnZXR0ZXh0IGlzIHRoZSBwcm9ncmFtIHRoYXQgc2NhbnMgc291cmNlIGNvZGUKbG9va2luZyBmb3IgbWVzc2FnZSBzdHJpbmdzLCBidXQgaXQgZ3Jva3Mgb25seSBDIChvciBDKyspLiBQeXRob24KaW50cm9kdWNlcyBhIGZldyB3cmlua2xlcywgc3VjaCBhcyBkdWFsIHF1b3RpbmcgY2hhcmFjdGVycywgdHJpcGxlIHF1b3RlZApzdHJpbmdzLCBhbmQgcmF3IHN0cmluZ3MuIHhnZXR0ZXh0IHVuZGVyc3RhbmRzIG5vbmUgb2YgdGhpcy4KCkVudGVyIHB5Z2V0dGV4dCwgd2hpY2ggdXNlcyBQeXRob24ncyBzdGFuZGFyZCB0b2tlbml6ZSBtb2R1bGUgdG8gc2NhbgpQeXRob24gc291cmNlIGNvZGUsIGdlbmVyYXRpbmcgLnBvdCBmaWxlcyBpZGVudGljYWwgdG8gd2hhdCBHTlUgeGdldHRleHRbMl0KZ2VuZXJhdGVzIGZvciBDIGFuZCBDKysgY29kZS4gRnJvbSB0aGVyZSwgdGhlIHN0YW5kYXJkIEdOVSB0b29scyBjYW4gYmUKdXNlZC4KCkEgd29yZCBhYm91dCBtYXJraW5nIFB5dGhvbiBzdHJpbmdzIGFzIGNhbmRpZGF0ZXMgZm9yIHRyYW5zbGF0aW9uLiBHTlUKeGdldHRleHQgcmVjb2duaXplcyB0aGUgZm9sbG93aW5nIGtleXdvcmRzOiBnZXR0ZXh0LCBkZ2V0dGV4dCwgZGNnZXR0ZXh0LAphbmQgZ2V0dGV4dF9ub29wLiBCdXQgdGhvc2UgY2FuIGJlIGEgbG90IG9mIHRleHQgdG8gaW5jbHVkZSBhbGwgb3ZlciB5b3VyCmNvZGUuIEMgYW5kIEMrKyBoYXZlIGEgdHJpY2s6IHRoZXkgdXNlIHRoZSBDIHByZXByb2Nlc3Nvci4gTW9zdAppbnRlcm5hdGlvbmFsaXplZCBDIHNvdXJjZSBpbmNsdWRlcyBhICNkZWZpbmUgZm9yIGdldHRleHQoKSB0byBfKCkgc28gdGhhdAp3aGF0IGhhcyB0byBiZSB3cml0dGVuIGluIHRoZSBzb3VyY2UgaXMgbXVjaCBsZXNzLiBUaHVzIHRoZXNlIGFyZSBib3RoCnRyYW5zbGF0YWJsZSBzdHJpbmdzOgoKICAgIGdldHRleHQoIlRyYW5zbGF0YWJsZSBTdHJpbmciKQogICAgXygiVHJhbnNsYXRhYmxlIFN0cmluZyIpCgpQeXRob24gb2YgY291cnNlIGhhcyBubyBwcmVwcm9jZXNzb3Igc28gdGhpcyBkb2Vzbid0IHdvcmsgc28gd2VsbC4gIFRodXMsCnB5Z2V0dGV4dCBzZWFyY2hlcyBvbmx5IGZvciBfKCkgYnkgZGVmYXVsdCwgYnV0IHNlZSB0aGUgLWsvLS1rZXl3b3JkIGZsYWcKYmVsb3cgZm9yIGhvdyB0byBhdWdtZW50IHRoaXMuCgogWzFdIGh0dHBzOi8vd3d3LnB5dGhvbi5vcmcvd29ya3Nob3BzLzE5OTctMTAvcHJvY2VlZGluZ3MvbG9ld2lzLmh0bWwKIFsyXSBodHRwczovL3d3dy5nbnUub3JnL3NvZnR3YXJlL2dldHRleHQvZ2V0dGV4dC5odG1sCgpOT1RFOiBweWdldHRleHQgYXR0ZW1wdHMgdG8gYmUgb3B0aW9uIGFuZCBmZWF0dXJlIGNvbXBhdGlibGUgd2l0aCBHTlUKeGdldHRleHQgd2hlcmUgZXZlciBwb3NzaWJsZS4gSG93ZXZlciBzb21lIG9wdGlvbnMgYXJlIHN0aWxsIG1pc3Npbmcgb3IgYXJlCm5vdCBmdWxseSBpbXBsZW1lbnRlZC4gQWxzbywgeGdldHRleHQncyB1c2Ugb2YgY29tbWFuZCBsaW5lIHN3aXRjaGVzIHdpdGgKb3B0aW9uIGFyZ3VtZW50cyBpcyBicm9rZW4sIGFuZCBpbiB0aGVzZSBjYXNlcywgcHlnZXR0ZXh0IGp1c3QgZGVmaW5lcwphZGRpdGlvbmFsIHN3aXRjaGVzLgoKVXNhZ2U6IHB5Z2V0dGV4dCBbb3B0aW9uc10gaW5wdXRmaWxlIC4uLgoKT3B0aW9uczoKCiAgICAtYQogICAgLS1leHRyYWN0LWFsbAogICAgICAgIEV4dHJhY3QgYWxsIHN0cmluZ3MuCgogICAgLWQgbmFtZQogICAgLS1kZWZhdWx0LWRvbWFpbj1uYW1lCiAgICAgICAgUmVuYW1lIHRoZSBkZWZhdWx0IG91dHB1dCBmaWxlIGZyb20gbWVzc2FnZXMucG90IHRvIG5hbWUucG90LgoKICAgIC1FCiAgICAtLWVzY2FwZQogICAgICAgIFJlcGxhY2Ugbm9uLUFTQ0lJIGNoYXJhY3RlcnMgd2l0aCBvY3RhbCBlc2NhcGUgc2VxdWVuY2VzLgoKICAgIC1ECiAgICAtLWRvY3N0cmluZ3MKICAgICAgICBFeHRyYWN0IG1vZHVsZSwgY2xhc3MsIG1ldGhvZCwgYW5kIGZ1bmN0aW9uIGRvY3N0cmluZ3MuICBUaGVzZSBkbwogICAgICAgIG5vdCBuZWVkIHRvIGJlIHdyYXBwZWQgaW4gXygpIG1hcmtlcnMsIGFuZCBpbiBmYWN0IGNhbm5vdCBiZSBmb3IKICAgICAgICBQeXRob24gdG8gY29uc2lkZXIgdGhlbSBkb2NzdHJpbmdzLiAoU2VlIGFsc28gdGhlIC1YIG9wdGlvbikuCgogICAgLWgKICAgIC0taGVscAogICAgICAgIFByaW50IHRoaXMgaGVscCBtZXNzYWdlIGFuZCBleGl0LgoKICAgIC1rIHdvcmQKICAgIC0ta2V5d29yZD13b3JkCiAgICAgICAgS2V5d29yZHMgdG8gbG9vayBmb3IgaW4gYWRkaXRpb24gdG8gdGhlIGRlZmF1bHQgc2V0LCB3aGljaCBhcmU6CiAgICAgICAgJShERUZBVUxUS0VZV09SRFMpcwoKICAgICAgICBZb3UgY2FuIGhhdmUgbXVsdGlwbGUgLWsgZmxhZ3Mgb24gdGhlIGNvbW1hbmQgbGluZS4KCiAgICAtSwogICAgLS1uby1kZWZhdWx0LWtleXdvcmRzCiAgICAgICAgRGlzYWJsZSB0aGUgZGVmYXVsdCBzZXQgb2Yga2V5d29yZHMgKHNlZSBhYm92ZSkuICBBbnkga2V5d29yZHMKICAgICAgICBleHBsaWNpdGx5IGFkZGVkIHdpdGggdGhlIC1rLy0ta2V5d29yZCBvcHRpb24gYXJlIHN0aWxsIHJlY29nbml6ZWQuCgogICAgLS1uby1sb2NhdGlvbgogICAgICAgIERvIG5vdCB3cml0ZSBmaWxlbmFtZS9saW5lbm8gbG9jYXRpb24gY29tbWVudHMuCgogICAgLW4KICAgIC0tYWRkLWxvY2F0aW9uCiAgICAgICAgV3JpdGUgZmlsZW5hbWUvbGluZW5vIGxvY2F0aW9uIGNvbW1lbnRzIGluZGljYXRpbmcgd2hlcmUgZWFjaAogICAgICAgIGV4dHJhY3RlZCBzdHJpbmcgaXMgZm91bmQgaW4gdGhlIHNvdXJjZS4gIFRoZXNlIGxpbmVzIGFwcGVhciBiZWZvcmUKICAgICAgICBlYWNoIG1zZ2lkLiAgVGhlIHN0eWxlIG9mIGNvbW1lbnRzIGlzIGNvbnRyb2xsZWQgYnkgdGhlIC1TLy0tc3R5bGUKICAgICAgICBvcHRpb24uICBUaGlzIGlzIHRoZSBkZWZhdWx0LgoKICAgIC1vIGZpbGVuYW1lCiAgICAtLW91dHB1dD1maWxlbmFtZQogICAgICAgIFJlbmFtZSB0aGUgZGVmYXVsdCBvdXRwdXQgZmlsZSBmcm9tIG1lc3NhZ2VzLnBvdCB0byBmaWxlbmFtZS4gIElmCiAgICAgICAgZmlsZW5hbWUgaXMgYC0nIHRoZW4gdGhlIG91dHB1dCBpcyBzZW50IHRvIHN0YW5kYXJkIG91dC4KCiAgICAtcCBkaXIKICAgIC0tb3V0cHV0LWRpcj1kaXIKICAgICAgICBPdXRwdXQgZmlsZXMgd2lsbCBiZSBwbGFjZWQgaW4gZGlyZWN0b3J5IGRpci4KCiAgICAtUyBzdHlsZW5hbWUKICAgIC0tc3R5bGUgc3R5bGVuYW1lCiAgICAgICAgU3BlY2lmeSB3aGljaCBzdHlsZSB0byB1c2UgZm9yIGxvY2F0aW9uIGNvbW1lbnRzLiAgVHdvIHN0eWxlcyBhcmUKICAgICAgICBzdXBwb3J0ZWQ6CgogICAgICAgIFNvbGFyaXMgICMgRmlsZTogZmlsZW5hbWUsIGxpbmU6IGxpbmUtbnVtYmVyCiAgICAgICAgR05VICAgICAgIzogZmlsZW5hbWU6bGluZQoKICAgICAgICBUaGUgc3R5bGUgbmFtZSBpcyBjYXNlIGluc2Vuc2l0aXZlLiAgR05VIHN0eWxlIGlzIHRoZSBkZWZhdWx0LgoKICAgIC12CiAgICAtLXZlcmJvc2UKICAgICAgICBQcmludCB0aGUgbmFtZXMgb2YgdGhlIGZpbGVzIGJlaW5nIHByb2Nlc3NlZC4KCiAgICAtVgogICAgLS12ZXJzaW9uCiAgICAgICAgUHJpbnQgdGhlIHZlcnNpb24gb2YgcHlnZXR0ZXh0IGFuZCBleGl0LgoKICAgIC13IGNvbHVtbnMKICAgIC0td2lkdGg9Y29sdW1ucwogICAgICAgIFNldCB3aWR0aCBvZiBvdXRwdXQgdG8gY29sdW1ucy4KCiAgICAteCBmaWxlbmFtZQogICAgLS1leGNsdWRlLWZpbGU9ZmlsZW5hbWUKICAgICAgICBTcGVjaWZ5IGEgZmlsZSB0aGF0IGNvbnRhaW5zIGEgbGlzdCBvZiBzdHJpbmdzIHRoYXQgYXJlIG5vdCBiZQogICAgICAgIGV4dHJhY3RlZCBmcm9tIHRoZSBpbnB1dCBmaWxlcy4gIEVhY2ggc3RyaW5nIHRvIGJlIGV4Y2x1ZGVkIG11c3QKICAgICAgICBhcHBlYXIgb24gYSBsaW5lIGJ5IGl0c2VsZiBpbiB0aGUgZmlsZS4KCiAgICAtWCBmaWxlbmFtZQogICAgLS1uby1kb2NzdHJpbmdzPWZpbGVuYW1lCiAgICAgICAgU3BlY2lmeSBhIGZpbGUgdGhhdCBjb250YWlucyBhIGxpc3Qgb2YgZmlsZXMgKG9uZSBwZXIgbGluZSkgdGhhdAogICAgICAgIHNob3VsZCBub3QgaGF2ZSB0aGVpciBkb2NzdHJpbmdzIGV4dHJhY3RlZC4gIFRoaXMgaXMgb25seSB1c2VmdWwgaW4KICAgICAgICBjb25qdW5jdGlvbiB3aXRoIHRoZSAtRCBvcHRpb24gYWJvdmUuCgpJZiBgaW5wdXRmaWxlJyBpcyAtLCBzdGFuZGFyZCBpbnB1dCBpcyByZWFkLgoiIiIpCgppbXBvcnQgb3MKaW1wb3J0IGltcG9ydGxpYi5tYWNoaW5lcnkKaW1wb3J0IGltcG9ydGxpYi51dGlsCmltcG9ydCBzeXMKaW1wb3J0IGdsb2IKaW1wb3J0IHRpbWUKaW1wb3J0IGdldG9wdAppbXBvcnQgYXN0CmltcG9ydCB0b2tlbgppbXBvcnQgdG9rZW5pemUKCl9fdmVyc2lvbl9fID0gJzEuNScKCmRlZmF1bHRfa2V5d29yZHMgPSBbJ18nXQpERUZBVUxUS0VZV09SRFMgPSAnLCAnLmpvaW4oZGVmYXVsdF9rZXl3b3JkcykKCkVNUFRZU1RSSU5HID0gJycKCgojIFRoZSBub3JtYWwgcG90LWZpbGUgaGVhZGVyLiBtc2dtZXJnZSBhbmQgRW1hY3MncyBwby1tb2RlIHdvcmsgYmV0dGVyIGlmIGl0J3MKIyB0aGVyZS4KcG90X2hlYWRlciA9IF8oJycnXAojIFNPTUUgREVTQ1JJUFRJVkUgVElUTEUuCiMgQ29weXJpZ2h0IChDKSBZRUFSIE9SR0FOSVpBVElPTgojIEZJUlNUIEFVVEhPUiA8RU1BSUxAQUREUkVTUz4sIFlFQVIuCiMKbXNnaWQgIiIKbXNnc3RyICIiCiJQcm9qZWN0LUlkLVZlcnNpb246IFBBQ0tBR0UgVkVSU0lPTlxcbiIKIlBPVC1DcmVhdGlvbi1EYXRlOiAlKHRpbWUpc1xcbiIKIlBPLVJldmlzaW9uLURhdGU6IFlFQVItTU8tREEgSE86TUkrWk9ORVxcbiIKIkxhc3QtVHJhbnNsYXRvcjogRlVMTCBOQU1FIDxFTUFJTEBBRERSRVNTPlxcbiIKIkxhbmd1YWdlLVRlYW06IExBTkdVQUdFIDxMTEBsaS5vcmc+XFxuIgoiTUlNRS1WZXJzaW9uOiAxLjBcXG4iCiJDb250ZW50LVR5cGU6IHRleHQvcGxhaW47IGNoYXJzZXQ9JShjaGFyc2V0KXNcXG4iCiJDb250ZW50LVRyYW5zZmVyLUVuY29kaW5nOiAlKGVuY29kaW5nKXNcXG4iCiJHZW5lcmF0ZWQtQnk6IHB5Z2V0dGV4dC5weSAlKHZlcnNpb24pc1xcbiIKCicnJykKCgpkZWYgdXNhZ2UoY29kZSwgbXNnPScnKToKICAgIHByaW50KF9fZG9jX18gJSBnbG9iYWxzKCksIGZpbGU9c3lzLnN0ZGVycikKICAgIGlmIG1zZzoKICAgICAgICBwcmludChtc2csIGZpbGU9c3lzLnN0ZGVycikKICAgIHN5cy5leGl0KGNvZGUpCgoKZGVmIG1ha2VfZXNjYXBlcyhwYXNzX25vbmFzY2lpKToKICAgIGdsb2JhbCBlc2NhcGVzLCBlc2NhcGUKICAgIGlmIHBhc3Nfbm9uYXNjaWk6CiAgICAgICAgIyBBbGxvdyBub24tYXNjaWkgY2hhcmFjdGVycyB0byBwYXNzIHRocm91Z2ggc28gdGhhdCBlLmcuICdtc2dpZAogICAgICAgICMgIkj2aGUiJyB3b3VsZCByZXN1bHQgbm90IHJlc3VsdCBpbiAnbXNnaWQgIkhcMzY2aGUiJy4gIE90aGVyd2lzZSB3ZQogICAgICAgICMgZXNjYXBlIGFueSBjaGFyYWN0ZXIgb3V0c2lkZSB0aGUgMzIuLjEyNiByYW5nZS4KICAgICAgICBtb2QgPSAxMjgKICAgICAgICBlc2NhcGUgPSBlc2NhcGVfYXNjaWkKICAgIGVsc2U6CiAgICAgICAgbW9kID0gMjU2CiAgICAgICAgZXNjYXBlID0gZXNjYXBlX25vbmFzY2lpCiAgICBlc2NhcGVzID0gW3IiXCUwM28iICUgaSBmb3IgaSBpbiByYW5nZShtb2QpXQogICAgZm9yIGkgaW4gcmFuZ2UoMzIsIDEyNyk6CiAgICAgICAgZXNjYXBlc1tpXSA9IGNocihpKQogICAgZXNjYXBlc1tvcmQoJ1xcJyldID0gcidcXCcKICAgIGVzY2FwZXNbb3JkKCdcdCcpXSA9IHInXHQnCiAgICBlc2NhcGVzW29yZCgnXHInKV0gPSByJ1xyJwogICAgZXNjYXBlc1tvcmQoJ1xuJyldID0gcidcbicKICAgIGVzY2FwZXNbb3JkKCdcIicpXSA9IHInXCInCgoKZGVmIGVzY2FwZV9hc2NpaShzLCBlbmNvZGluZyk6CiAgICByZXR1cm4gJycuam9pbihlc2NhcGVzW29yZChjKV0gaWYgb3JkKGMpIDwgMTI4IGVsc2UgYyBmb3IgYyBpbiBzKQoKZGVmIGVzY2FwZV9ub25hc2NpaShzLCBlbmNvZGluZyk6CiAgICByZXR1cm4gJycuam9pbihlc2NhcGVzW2JdIGZvciBiIGluIHMuZW5jb2RlKGVuY29kaW5nKSkKCgpkZWYgaXNfbGl0ZXJhbF9zdHJpbmcocyk6CiAgICByZXR1cm4gc1swXSBpbiAnXCciJyBvciAoc1swXSBpbiAnclJ1VScgYW5kIHNbMV0gaW4gJ1wnIicpCgoKZGVmIHNhZmVfZXZhbChzKToKICAgICMgdW53cmFwIHF1b3Rlcywgc2FmZWx5CiAgICByZXR1cm4gZXZhbChzLCB7J19fYnVpbHRpbnNfXyc6e319LCB7fSkKCgpkZWYgbm9ybWFsaXplKHMsIGVuY29kaW5nKToKICAgICMgVGhpcyBjb252ZXJ0cyB0aGUgdmFyaW91cyBQeXRob24gc3RyaW5nIHR5cGVzIGludG8gYSBmb3JtYXQgdGhhdCBpcwogICAgIyBhcHByb3ByaWF0ZSBmb3IgLnBvIGZpbGVzLCBuYW1lbHkgbXVjaCBjbG9zZXIgdG8gQyBzdHlsZS4KICAgIGxpbmVzID0gcy5zcGxpdCgnXG4nKQogICAgaWYgbGVuKGxpbmVzKSA9PSAxOgogICAgICAgIHMgPSAnIicgKyBlc2NhcGUocywgZW5jb2RpbmcpICsgJyInCiAgICBlbHNlOgogICAgICAgIGlmIG5vdCBsaW5lc1stMV06CiAgICAgICAgICAgIGRlbCBsaW5lc1stMV0KICAgICAgICAgICAgbGluZXNbLTFdID0gbGluZXNbLTFdICsgJ1xuJwogICAgICAgIGZvciBpIGluIHJhbmdlKGxlbihsaW5lcykpOgogICAgICAgICAgICBsaW5lc1tpXSA9IGVzY2FwZShsaW5lc1tpXSwgZW5jb2RpbmcpCiAgICAgICAgbGluZXRlcm0gPSAnXFxuIlxuIicKICAgICAgICBzID0gJyIiXG4iJyArIGxpbmV0ZXJtLmpvaW4obGluZXMpICsgJyInCiAgICByZXR1cm4gcwoKCmRlZiBjb250YWluc0FueShzdHIsIHNldCk6CiAgICAiIiJDaGVjayB3aGV0aGVyICdzdHInIGNvbnRhaW5zIEFOWSBvZiB0aGUgY2hhcnMgaW4gJ3NldCciIiIKICAgIHJldHVybiAxIGluIFtjIGluIHN0ciBmb3IgYyBpbiBzZXRdCgoKZGVmIGdldEZpbGVzRm9yTmFtZShuYW1lKToKICAgICIiIkdldCBhIGxpc3Qgb2YgbW9kdWxlIGZpbGVzIGZvciBhIGZpbGVuYW1lLCBhIG1vZHVsZSBvciBwYWNrYWdlIG5hbWUsCiAgICBvciBhIGRpcmVjdG9yeS4KICAgICIiIgogICAgaWYgbm90IG9zLnBhdGguZXhpc3RzKG5hbWUpOgogICAgICAgICMgY2hlY2sgZm9yIGdsb2IgY2hhcnMKICAgICAgICBpZiBjb250YWluc0FueShuYW1lLCAiKj9bXSIpOgogICAgICAgICAgICBmaWxlcyA9IGdsb2IuZ2xvYihuYW1lKQogICAgICAgICAgICBsaXN0ID0gW10KICAgICAgICAgICAgZm9yIGZpbGUgaW4gZmlsZXM6CiAgICAgICAgICAgICAgICBsaXN0LmV4dGVuZChnZXRGaWxlc0Zvck5hbWUoZmlsZSkpCiAgICAgICAgICAgIHJldHVybiBsaXN0CgogICAgICAgICMgdHJ5IHRvIGZpbmQgbW9kdWxlIG9yIHBhY2thZ2UKICAgICAgICB0cnk6CiAgICAgICAgICAgIHNwZWMgPSBpbXBvcnRsaWIudXRpbC5maW5kX3NwZWMobmFtZSkKICAgICAgICAgICAgbmFtZSA9IHNwZWMub3JpZ2luCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOgogICAgICAgICAgICBuYW1lID0gTm9uZQogICAgICAgIGlmIG5vdCBuYW1lOgogICAgICAgICAgICByZXR1cm4gW10KCiAgICBpZiBvcy5wYXRoLmlzZGlyKG5hbWUpOgogICAgICAgICMgZmluZCBhbGwgcHl0aG9uIGZpbGVzIGluIGRpcmVjdG9yeQogICAgICAgIGxpc3QgPSBbXQogICAgICAgICMgZ2V0IGV4dGVuc2lvbiBmb3IgcHl0aG9uIHNvdXJjZSBmaWxlcwogICAgICAgIF9weV9leHQgPSBpbXBvcnRsaWIubWFjaGluZXJ5LlNPVVJDRV9TVUZGSVhFU1swXQogICAgICAgIGZvciByb290LCBkaXJzLCBmaWxlcyBpbiBvcy53YWxrKG5hbWUpOgogICAgICAgICAgICAjIGRvbid0IHJlY3Vyc2UgaW50byBDVlMgZGlyZWN0b3JpZXMKICAgICAgICAgICAgaWYgJ0NWUycgaW4gZGlyczoKICAgICAgICAgICAgICAgIGRpcnMucmVtb3ZlKCdDVlMnKQogICAgICAgICAgICAjIGFkZCBhbGwgKi5weSBmaWxlcyB0byBsaXN0CiAgICAgICAgICAgIGxpc3QuZXh0ZW5kKAogICAgICAgICAgICAgICAgW29zLnBhdGguam9pbihyb290LCBmaWxlKSBmb3IgZmlsZSBpbiBmaWxlcwogICAgICAgICAgICAgICAgIGlmIG9zLnBhdGguc3BsaXRleHQoZmlsZSlbMV0gPT0gX3B5X2V4dF0KICAgICAgICAgICAgICAgICkKICAgICAgICByZXR1cm4gbGlzdAogICAgZWxpZiBvcy5wYXRoLmV4aXN0cyhuYW1lKToKICAgICAgICAjIGEgc2luZ2xlIGZpbGUKICAgICAgICByZXR1cm4gW25hbWVdCgogICAgcmV0dXJuIFtdCgoKY2xhc3MgVG9rZW5FYXRlcjoKICAgIGRlZiBfX2luaXRfXyhzZWxmLCBvcHRpb25zKToKICAgICAgICBzZWxmLl9fb3B0aW9ucyA9IG9wdGlvbnMKICAgICAgICBzZWxmLl9fbWVzc2FnZXMgPSB7fQogICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nCiAgICAgICAgc2VsZi5fX2RhdGEgPSBbXQogICAgICAgIHNlbGYuX19saW5lbm8gPSAtMQogICAgICAgIHNlbGYuX19mcmVzaG1vZHVsZSA9IDEKICAgICAgICBzZWxmLl9fY3VyZmlsZSA9IE5vbmUKICAgICAgICBzZWxmLl9fZW5jbG9zdXJlY291bnQgPSAwCgogICAgZGVmIF9fY2FsbF9fKHNlbGYsIHR0eXBlLCB0c3RyaW5nLCBzdHVwLCBldHVwLCBsaW5lKToKICAgICAgICAjIGRpc3BhdGNoCiMjICAgICAgICBpbXBvcnQgdG9rZW4KIyMgICAgICAgIHByaW50KCd0dHlwZTonLCB0b2tlbi50b2tfbmFtZVt0dHlwZV0sICd0c3RyaW5nOicsIHRzdHJpbmcsCiMjICAgICAgICAgICAgICBmaWxlPXN5cy5zdGRlcnIpCiAgICAgICAgc2VsZi5fX3N0YXRlKHR0eXBlLCB0c3RyaW5nLCBzdHVwWzBdKQoKICAgIGRlZiBfX3dhaXRpbmcoc2VsZiwgdHR5cGUsIHRzdHJpbmcsIGxpbmVubyk6CiAgICAgICAgb3B0cyA9IHNlbGYuX19vcHRpb25zCiAgICAgICAgIyBEbyBkb2NzdHJpbmcgZXh0cmFjdGlvbnMsIGlmIGVuYWJsZWQKICAgICAgICBpZiBvcHRzLmRvY3N0cmluZ3MgYW5kIG5vdCBvcHRzLm5vZG9jc3RyaW5ncy5nZXQoc2VsZi5fX2N1cmZpbGUpOgogICAgICAgICAgICAjIG1vZHVsZSBkb2NzdHJpbmc/CiAgICAgICAgICAgIGlmIHNlbGYuX19mcmVzaG1vZHVsZToKICAgICAgICAgICAgICAgIGlmIHR0eXBlID09IHRva2VuaXplLlNUUklORyBhbmQgaXNfbGl0ZXJhbF9zdHJpbmcodHN0cmluZyk6CiAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2FkZGVudHJ5KHNhZmVfZXZhbCh0c3RyaW5nKSwgbGluZW5vLCBpc2RvY3N0cmluZz0xKQogICAgICAgICAgICAgICAgICAgIHNlbGYuX19mcmVzaG1vZHVsZSA9IDAKICAgICAgICAgICAgICAgICAgICByZXR1cm4KICAgICAgICAgICAgICAgIGlmIHR0eXBlIGluICh0b2tlbml6ZS5DT01NRU5ULCB0b2tlbml6ZS5OTCwgdG9rZW5pemUuRU5DT0RJTkcpOgogICAgICAgICAgICAgICAgICAgIHJldHVybgogICAgICAgICAgICAgICAgc2VsZi5fX2ZyZXNobW9kdWxlID0gMAogICAgICAgICAgICAjIGNsYXNzIG9yIGZ1bmMvbWV0aG9kIGRvY3N0cmluZz8KICAgICAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuTkFNRSBhbmQgdHN0cmluZyBpbiAoJ2NsYXNzJywgJ2RlZicpOgogICAgICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3N1aXRlc2VlbgogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuTkFNRSBhbmQgdHN0cmluZyBpbiBvcHRzLmtleXdvcmRzOgogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fa2V5d29yZHNlZW4KICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuU1RSSU5HOgogICAgICAgICAgICBtYXliZV9mc3RyaW5nID0gYXN0LnBhcnNlKHRzdHJpbmcsIG1vZGU9J2V2YWwnKS5ib2R5CiAgICAgICAgICAgIGlmIG5vdCBpc2luc3RhbmNlKG1heWJlX2ZzdHJpbmcsIGFzdC5Kb2luZWRTdHIpOgogICAgICAgICAgICAgICAgcmV0dXJuCiAgICAgICAgICAgIGZvciB2YWx1ZSBpbiBmaWx0ZXIobGFtYmRhIG5vZGU6IGlzaW5zdGFuY2Uobm9kZSwgYXN0LkZvcm1hdHRlZFZhbHVlKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBtYXliZV9mc3RyaW5nLnZhbHVlcyk6CiAgICAgICAgICAgICAgICBmb3IgY2FsbCBpbiBmaWx0ZXIobGFtYmRhIG5vZGU6IGlzaW5zdGFuY2Uobm9kZSwgYXN0LkNhbGwpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFzdC53YWxrKHZhbHVlKSk6CiAgICAgICAgICAgICAgICAgICAgZnVuYyA9IGNhbGwuZnVuYwogICAgICAgICAgICAgICAgICAgIGlmIGlzaW5zdGFuY2UoZnVuYywgYXN0Lk5hbWUpOgogICAgICAgICAgICAgICAgICAgICAgICBmdW5jX25hbWUgPSBmdW5jLmlkCiAgICAgICAgICAgICAgICAgICAgZWxpZiBpc2luc3RhbmNlKGZ1bmMsIGFzdC5BdHRyaWJ1dGUpOgogICAgICAgICAgICAgICAgICAgICAgICBmdW5jX25hbWUgPSBmdW5jLmF0dHIKICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICBjb250aW51ZQoKICAgICAgICAgICAgICAgICAgICBpZiBmdW5jX25hbWUgbm90IGluIG9wdHMua2V5d29yZHM6CiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICAgICAgaWYgbGVuKGNhbGwuYXJncykgIT0gMToKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoXygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICcqKiogJShmaWxlKXM6JShsaW5lbm8pczogU2VlbiB1bmV4cGVjdGVkIGFtb3VudCBvZicKICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgcG9zaXRpb25hbCBhcmd1bWVudHMgaW4gZ2V0dGV4dCBjYWxsOiAlKHNvdXJjZV9zZWdtZW50KXMnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApICUgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NvdXJjZV9zZWdtZW50JzogYXN0LmdldF9zb3VyY2Vfc2VnbWVudCh0c3RyaW5nLCBjYWxsKSBvciB0c3RyaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZpbGUnOiBzZWxmLl9fY3VyZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdsaW5lbm8nOiBsaW5lbm8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIGZpbGU9c3lzLnN0ZGVycikKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgICAgICBpZiBjYWxsLmtleXdvcmRzOgogICAgICAgICAgICAgICAgICAgICAgICBwcmludChfKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJyoqKiAlKGZpbGUpczolKGxpbmVubylzOiBTZWVuIHVuZXhwZWN0ZWQga2V5d29yZCBhcmd1bWVudHMnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnIGluIGdldHRleHQgY2FsbDogJShzb3VyY2Vfc2VnbWVudClzJwogICAgICAgICAgICAgICAgICAgICAgICAgICAgKSAlIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdzb3VyY2Vfc2VnbWVudCc6IGFzdC5nZXRfc291cmNlX3NlZ21lbnQodHN0cmluZywgY2FsbCkgb3IgdHN0cmluZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdmaWxlJzogc2VsZi5fX2N1cmZpbGUsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnbGluZW5vJzogbGluZW5vCiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LCBmaWxlPXN5cy5zdGRlcnIpCiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRpbnVlCiAgICAgICAgICAgICAgICAgICAgYXJnID0gY2FsbC5hcmdzWzBdCiAgICAgICAgICAgICAgICAgICAgaWYgbm90IGlzaW5zdGFuY2UoYXJnLCBhc3QuQ29uc3RhbnQpOgogICAgICAgICAgICAgICAgICAgICAgICBwcmludChfKAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJyoqKiAlKGZpbGUpczolKGxpbmVubylzOiBTZWVuIHVuZXhwZWN0ZWQgYXJndW1lbnQgdHlwZScKICAgICAgICAgICAgICAgICAgICAgICAgICAgICcgaW4gZ2V0dGV4dCBjYWxsOiAlKHNvdXJjZV9zZWdtZW50KXMnCiAgICAgICAgICAgICAgICAgICAgICAgICAgICApICUgewogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ3NvdXJjZV9zZWdtZW50JzogYXN0LmdldF9zb3VyY2Vfc2VnbWVudCh0c3RyaW5nLCBjYWxsKSBvciB0c3RyaW5nLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgJ2ZpbGUnOiBzZWxmLl9fY3VyZmlsZSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdsaW5lbm8nOiBsaW5lbm8KICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sIGZpbGU9c3lzLnN0ZGVycikKICAgICAgICAgICAgICAgICAgICAgICAgY29udGludWUKICAgICAgICAgICAgICAgICAgICBpZiBpc2luc3RhbmNlKGFyZy52YWx1ZSwgc3RyKToKICAgICAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2FkZGVudHJ5KGFyZy52YWx1ZSwgbGluZW5vKQoKICAgIGRlZiBfX3N1aXRlc2VlbihzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToKICAgICAgICAjIHNraXAgb3ZlciBhbnkgZW5jbG9zdXJlIHBhaXJzIHVudGlsIHdlIHNlZSB0aGUgY29sb24KICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5PUDoKICAgICAgICAgICAgaWYgdHN0cmluZyA9PSAnOicgYW5kIHNlbGYuX19lbmNsb3N1cmVjb3VudCA9PSAwOgogICAgICAgICAgICAgICAgIyB3ZSBzZWUgYSBjb2xvbiBhbmQgd2UncmUgbm90IGluIGFuIGVuY2xvc3VyZTogZW5kIG9mIGRlZgogICAgICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3N1aXRlZG9jc3RyaW5nCiAgICAgICAgICAgIGVsaWYgdHN0cmluZyBpbiAnKFt7JzoKICAgICAgICAgICAgICAgIHNlbGYuX19lbmNsb3N1cmVjb3VudCArPSAxCiAgICAgICAgICAgIGVsaWYgdHN0cmluZyBpbiAnKV19JzoKICAgICAgICAgICAgICAgIHNlbGYuX19lbmNsb3N1cmVjb3VudCAtPSAxCgogICAgZGVmIF9fc3VpdGVkb2NzdHJpbmcoc2VsZiwgdHR5cGUsIHRzdHJpbmcsIGxpbmVubyk6CiAgICAgICAgIyBpZ25vcmUgYW55IGludGVydmVuaW5nIG5vaXNlCiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuU1RSSU5HIGFuZCBpc19saXRlcmFsX3N0cmluZyh0c3RyaW5nKToKICAgICAgICAgICAgc2VsZi5fX2FkZGVudHJ5KHNhZmVfZXZhbCh0c3RyaW5nKSwgbGluZW5vLCBpc2RvY3N0cmluZz0xKQogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZwogICAgICAgIGVsaWYgdHR5cGUgbm90IGluICh0b2tlbml6ZS5ORVdMSU5FLCB0b2tlbml6ZS5JTkRFTlQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIHRva2VuaXplLkNPTU1FTlQpOgogICAgICAgICAgICAjIHRoZXJlIHdhcyBubyBjbGFzcyBkb2NzdHJpbmcKICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3dhaXRpbmcKCiAgICBkZWYgX19rZXl3b3Jkc2VlbihzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToKICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5PUCBhbmQgdHN0cmluZyA9PSAnKCc6CiAgICAgICAgICAgIHNlbGYuX19kYXRhID0gW10KICAgICAgICAgICAgc2VsZi5fX2xpbmVubyA9IGxpbmVubwogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fb3BlbnNlZW4KICAgICAgICBlbHNlOgogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZwoKICAgIGRlZiBfX29wZW5zZWVuKHNlbGYsIHR0eXBlLCB0c3RyaW5nLCBsaW5lbm8pOgogICAgICAgIGlmIHR0eXBlID09IHRva2VuaXplLk9QIGFuZCB0c3RyaW5nID09ICcpJzoKICAgICAgICAgICAgIyBXZSd2ZSBzZWVuIHRoZSBsYXN0IG9mIHRoZSB0cmFuc2xhdGFibGUgc3RyaW5ncy4gIFJlY29yZCB0aGUKICAgICAgICAgICAgIyBsaW5lIG51bWJlciBvZiB0aGUgZmlyc3QgbGluZSBvZiB0aGUgc3RyaW5ncyBhbmQgdXBkYXRlIHRoZSBsaXN0CiAgICAgICAgICAgICMgb2YgbWVzc2FnZXMgc2Vlbi4gIFJlc2V0IHN0YXRlIGZvciB0aGUgbmV4dCBiYXRjaC4gIElmIHRoZXJlCiAgICAgICAgICAgICMgd2VyZSBubyBzdHJpbmdzIGluc2lkZSBfKCksIHRoZW4ganVzdCBpZ25vcmUgdGhpcyBlbnRyeS4KICAgICAgICAgICAgaWYgc2VsZi5fX2RhdGE6CiAgICAgICAgICAgICAgICBzZWxmLl9fYWRkZW50cnkoRU1QVFlTVFJJTkcuam9pbihzZWxmLl9fZGF0YSkpCiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nCiAgICAgICAgZWxpZiB0dHlwZSA9PSB0b2tlbml6ZS5TVFJJTkcgYW5kIGlzX2xpdGVyYWxfc3RyaW5nKHRzdHJpbmcpOgogICAgICAgICAgICBzZWxmLl9fZGF0YS5hcHBlbmQoc2FmZV9ldmFsKHRzdHJpbmcpKQogICAgICAgIGVsaWYgdHR5cGUgbm90IGluIFt0b2tlbml6ZS5DT01NRU5ULCB0b2tlbi5JTkRFTlQsIHRva2VuLkRFREVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW4uTkVXTElORSwgdG9rZW5pemUuTkxdOgogICAgICAgICAgICAjIHdhcm4gaWYgd2Ugc2VlIGFueXRoaW5nIGVsc2UgdGhhbiBTVFJJTkcgb3Igd2hpdGVzcGFjZQogICAgICAgICAgICBwcmludChfKAogICAgICAgICAgICAgICAgJyoqKiAlKGZpbGUpczolKGxpbmVubylzOiBTZWVuIHVuZXhwZWN0ZWQgdG9rZW4gIiUodG9rZW4pcyInCiAgICAgICAgICAgICAgICApICUgewogICAgICAgICAgICAgICAgJ3Rva2VuJzogdHN0cmluZywKICAgICAgICAgICAgICAgICdmaWxlJzogc2VsZi5fX2N1cmZpbGUsCiAgICAgICAgICAgICAgICAnbGluZW5vJzogc2VsZi5fX2xpbmVubwogICAgICAgICAgICAgICAgfSwgZmlsZT1zeXMuc3RkZXJyKQogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZwoKICAgIGRlZiBfX2FkZGVudHJ5KHNlbGYsIG1zZywgbGluZW5vPU5vbmUsIGlzZG9jc3RyaW5nPTApOgogICAgICAgIGlmIGxpbmVubyBpcyBOb25lOgogICAgICAgICAgICBsaW5lbm8gPSBzZWxmLl9fbGluZW5vCiAgICAgICAgaWYgbm90IG1zZyBpbiBzZWxmLl9fb3B0aW9ucy50b2V4Y2x1ZGU6CiAgICAgICAgICAgIGVudHJ5ID0gKHNlbGYuX19jdXJmaWxlLCBsaW5lbm8pCiAgICAgICAgICAgIHNlbGYuX19tZXNzYWdlcy5zZXRkZWZhdWx0KG1zZywge30pW2VudHJ5XSA9IGlzZG9jc3RyaW5nCgogICAgZGVmIHNldF9maWxlbmFtZShzZWxmLCBmaWxlbmFtZSk6CiAgICAgICAgc2VsZi5fX2N1cmZpbGUgPSBmaWxlbmFtZQogICAgICAgIHNlbGYuX19mcmVzaG1vZHVsZSA9IDEKCiAgICBkZWYgd3JpdGUoc2VsZiwgZnApOgogICAgICAgIG9wdGlvbnMgPSBzZWxmLl9fb3B0aW9ucwogICAgICAgIHRpbWVzdGFtcCA9IHRpbWUuc3RyZnRpbWUoJyVZLSVtLSVkICVIOiVNJXonKQogICAgICAgIGVuY29kaW5nID0gZnAuZW5jb2RpbmcgaWYgZnAuZW5jb2RpbmcgZWxzZSAnVVRGLTgnCiAgICAgICAgcHJpbnQocG90X2hlYWRlciAlIHsndGltZSc6IHRpbWVzdGFtcCwgJ3ZlcnNpb24nOiBfX3ZlcnNpb25fXywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICdjaGFyc2V0JzogZW5jb2RpbmcsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAnZW5jb2RpbmcnOiAnOGJpdCd9LCBmaWxlPWZwKQogICAgICAgICMgU29ydCB0aGUgZW50cmllcy4gIEZpcnN0IHNvcnQgZWFjaCBwYXJ0aWN1bGFyIGVudHJ5J3Mga2V5cywgdGhlbgogICAgICAgICMgc29ydCBhbGwgdGhlIGVudHJpZXMgYnkgdGhlaXIgZmlyc3QgaXRlbS4KICAgICAgICByZXZlcnNlID0ge30KICAgICAgICBmb3IgaywgdiBpbiBzZWxmLl9fbWVzc2FnZXMuaXRlbXMoKToKICAgICAgICAgICAga2V5cyA9IHNvcnRlZCh2LmtleXMoKSkKICAgICAgICAgICAgcmV2ZXJzZS5zZXRkZWZhdWx0KHR1cGxlKGtleXMpLCBbXSkuYXBwZW5kKChrLCB2KSkKICAgICAgICBya2V5cyA9IHNvcnRlZChyZXZlcnNlLmtleXMoKSkKICAgICAgICBmb3IgcmtleSBpbiBya2V5czoKICAgICAgICAgICAgcmVudHJpZXMgPSByZXZlcnNlW3JrZXldCiAgICAgICAgICAgIHJlbnRyaWVzLnNvcnQoKQogICAgICAgICAgICBmb3IgaywgdiBpbiByZW50cmllczoKICAgICAgICAgICAgICAgICMgSWYgdGhlIGVudHJ5IHdhcyBnbGVhbmVkIG91dCBvZiBhIGRvY3N0cmluZywgdGhlbiBhZGQgYQogICAgICAgICAgICAgICAgIyBjb21tZW50IHN0YXRpbmcgc28uICBUaGlzIGlzIHRvIGFpZCB0cmFuc2xhdG9ycyB3aG8gbWF5IHdpc2gKICAgICAgICAgICAgICAgICMgdG8gc2tpcCB0cmFuc2xhdGluZyBzb21lIHVuaW1wb3J0YW50IGRvY3N0cmluZ3MuCiAgICAgICAgICAgICAgICBpc2RvY3N0cmluZyA9IGFueSh2LnZhbHVlcygpKQogICAgICAgICAgICAgICAgIyBrIGlzIHRoZSBtZXNzYWdlIHN0cmluZywgdiBpcyBhIGRpY3Rpb25hcnktc2V0IG9mIChmaWxlbmFtZSwKICAgICAgICAgICAgICAgICMgbGluZW5vKSB0dXBsZXMuICBXZSB3YW50IHRvIHNvcnQgdGhlIGVudHJpZXMgaW4gdiBmaXJzdCBieQogICAgICAgICAgICAgICAgIyBmaWxlIG5hbWUgYW5kIHRoZW4gYnkgbGluZSBudW1iZXIuCiAgICAgICAgICAgICAgICB2ID0gc29ydGVkKHYua2V5cygpKQogICAgICAgICAgICAgICAgaWYgbm90IG9wdGlvbnMud3JpdGVsb2NhdGlvbnM6CiAgICAgICAgICAgICAgICAgICAgcGFzcwogICAgICAgICAgICAgICAgIyBsb2NhdGlvbiBjb21tZW50cyBhcmUgZGlmZmVyZW50IGIvdyBTb2xhcmlzIGFuZCBHTlU6CiAgICAgICAgICAgICAgICBlbGlmIG9wdGlvbnMubG9jYXRpb25zdHlsZSA9PSBvcHRpb25zLlNPTEFSSVM6CiAgICAgICAgICAgICAgICAgICAgZm9yIGZpbGVuYW1lLCBsaW5lbm8gaW4gdjoKICAgICAgICAgICAgICAgICAgICAgICAgZCA9IHsnZmlsZW5hbWUnOiBmaWxlbmFtZSwgJ2xpbmVubyc6IGxpbmVub30KICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQoXygKICAgICAgICAgICAgICAgICAgICAgICAgICAgICcjIEZpbGU6ICUoZmlsZW5hbWUpcywgbGluZTogJShsaW5lbm8pZCcpICUgZCwgZmlsZT1mcCkKICAgICAgICAgICAgICAgIGVsaWYgb3B0aW9ucy5sb2NhdGlvbnN0eWxlID09IG9wdGlvbnMuR05VOgogICAgICAgICAgICAgICAgICAgICMgZml0IGFzIG1hbnkgbG9jYXRpb25zIG9uIG9uZSBsaW5lLCBhcyBsb25nIGFzIHRoZQogICAgICAgICAgICAgICAgICAgICMgcmVzdWx0aW5nIGxpbmUgbGVuZ3RoIGRvZXNuJ3QgZXhjZWVkICdvcHRpb25zLndpZHRoJwogICAgICAgICAgICAgICAgICAgIGxvY2xpbmUgPSAnIzonCiAgICAgICAgICAgICAgICAgICAgZm9yIGZpbGVuYW1lLCBsaW5lbm8gaW4gdjoKICAgICAgICAgICAgICAgICAgICAgICAgZCA9IHsnZmlsZW5hbWUnOiBmaWxlbmFtZSwgJ2xpbmVubyc6IGxpbmVub30KICAgICAgICAgICAgICAgICAgICAgICAgcyA9IF8oJyAlKGZpbGVuYW1lKXM6JShsaW5lbm8pZCcpICUgZAogICAgICAgICAgICAgICAgICAgICAgICBpZiBsZW4obG9jbGluZSkgKyBsZW4ocykgPD0gb3B0aW9ucy53aWR0aDoKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2xpbmUgPSBsb2NsaW5lICsgcwogICAgICAgICAgICAgICAgICAgICAgICBlbHNlOgogICAgICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnQobG9jbGluZSwgZmlsZT1mcCkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxvY2xpbmUgPSAiIzoiICsgcwogICAgICAgICAgICAgICAgICAgIGlmIGxlbihsb2NsaW5lKSA+IDI6CiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50KGxvY2xpbmUsIGZpbGU9ZnApCiAgICAgICAgICAgICAgICBpZiBpc2RvY3N0cmluZzoKICAgICAgICAgICAgICAgICAgICBwcmludCgnIywgZG9jc3RyaW5nJywgZmlsZT1mcCkKICAgICAgICAgICAgICAgIHByaW50KCdtc2dpZCcsIG5vcm1hbGl6ZShrLCBlbmNvZGluZyksIGZpbGU9ZnApCiAgICAgICAgICAgICAgICBwcmludCgnbXNnc3RyICIiXG4nLCBmaWxlPWZwKQoKCmRlZiBtYWluKCk6CiAgICBnbG9iYWwgZGVmYXVsdF9rZXl3b3JkcwogICAgdHJ5OgogICAgICAgIG9wdHMsIGFyZ3MgPSBnZXRvcHQuZ2V0b3B0KAogICAgICAgICAgICBzeXMuYXJndlsxOl0sCiAgICAgICAgICAgICdhZDpERWhrOktubzpwOlM6VnZ3Ong6WDonLAogICAgICAgICAgICBbJ2V4dHJhY3QtYWxsJywgJ2RlZmF1bHQtZG9tYWluPScsICdlc2NhcGUnLCAnaGVscCcsCiAgICAgICAgICAgICAna2V5d29yZD0nLCAnbm8tZGVmYXVsdC1rZXl3b3JkcycsCiAgICAgICAgICAgICAnYWRkLWxvY2F0aW9uJywgJ25vLWxvY2F0aW9uJywgJ291dHB1dD0nLCAnb3V0cHV0LWRpcj0nLAogICAgICAgICAgICAgJ3N0eWxlPScsICd2ZXJib3NlJywgJ3ZlcnNpb24nLCAnd2lkdGg9JywgJ2V4Y2x1ZGUtZmlsZT0nLAogICAgICAgICAgICAgJ2RvY3N0cmluZ3MnLCAnbm8tZG9jc3RyaW5ncycsCiAgICAgICAgICAgICBdKQogICAgZXhjZXB0IGdldG9wdC5lcnJvciBhcyBtc2c6CiAgICAgICAgdXNhZ2UoMSwgbXNnKQoKICAgICMgZm9yIGhvbGRpbmcgb3B0aW9uIHZhbHVlcwogICAgY2xhc3MgT3B0aW9uczoKICAgICAgICAjIGNvbnN0YW50cwogICAgICAgIEdOVSA9IDEKICAgICAgICBTT0xBUklTID0gMgogICAgICAgICMgZGVmYXVsdHMKICAgICAgICBleHRyYWN0YWxsID0gMCAjIEZJWE1FOiBjdXJyZW50bHkgdGhpcyBvcHRpb24gaGFzIG5vIGVmZmVjdCBhdCBhbGwuCiAgICAgICAgZXNjYXBlID0gMAogICAgICAgIGtleXdvcmRzID0gW10KICAgICAgICBvdXRwYXRoID0gJycKICAgICAgICBvdXRmaWxlID0gJ21lc3NhZ2VzLnBvdCcKICAgICAgICB3cml0ZWxvY2F0aW9ucyA9IDEKICAgICAgICBsb2NhdGlvbnN0eWxlID0gR05VCiAgICAgICAgdmVyYm9zZSA9IDAKICAgICAgICB3aWR0aCA9IDc4CiAgICAgICAgZXhjbHVkZWZpbGVuYW1lID0gJycKICAgICAgICBkb2NzdHJpbmdzID0gMAogICAgICAgIG5vZG9jc3RyaW5ncyA9IHt9CgogICAgb3B0aW9ucyA9IE9wdGlvbnMoKQogICAgbG9jYXRpb25zID0geydnbnUnIDogb3B0aW9ucy5HTlUsCiAgICAgICAgICAgICAgICAgJ3NvbGFyaXMnIDogb3B0aW9ucy5TT0xBUklTLAogICAgICAgICAgICAgICAgIH0KCiAgICAjIHBhcnNlIG9wdGlvbnMKICAgIGZvciBvcHQsIGFyZyBpbiBvcHRzOgogICAgICAgIGlmIG9wdCBpbiAoJy1oJywgJy0taGVscCcpOgogICAgICAgICAgICB1c2FnZSgwKQogICAgICAgIGVsaWYgb3B0IGluICgnLWEnLCAnLS1leHRyYWN0LWFsbCcpOgogICAgICAgICAgICBvcHRpb25zLmV4dHJhY3RhbGwgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctZCcsICctLWRlZmF1bHQtZG9tYWluJyk6CiAgICAgICAgICAgIG9wdGlvbnMub3V0ZmlsZSA9IGFyZyArICcucG90JwogICAgICAgIGVsaWYgb3B0IGluICgnLUUnLCAnLS1lc2NhcGUnKToKICAgICAgICAgICAgb3B0aW9ucy5lc2NhcGUgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctRCcsICctLWRvY3N0cmluZ3MnKToKICAgICAgICAgICAgb3B0aW9ucy5kb2NzdHJpbmdzID0gMQogICAgICAgIGVsaWYgb3B0IGluICgnLWsnLCAnLS1rZXl3b3JkJyk6CiAgICAgICAgICAgIG9wdGlvbnMua2V5d29yZHMuYXBwZW5kKGFyZykKICAgICAgICBlbGlmIG9wdCBpbiAoJy1LJywgJy0tbm8tZGVmYXVsdC1rZXl3b3JkcycpOgogICAgICAgICAgICBkZWZhdWx0X2tleXdvcmRzID0gW10KICAgICAgICBlbGlmIG9wdCBpbiAoJy1uJywgJy0tYWRkLWxvY2F0aW9uJyk6CiAgICAgICAgICAgIG9wdGlvbnMud3JpdGVsb2NhdGlvbnMgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctLW5vLWxvY2F0aW9uJywpOgogICAgICAgICAgICBvcHRpb25zLndyaXRlbG9jYXRpb25zID0gMAogICAgICAgIGVsaWYgb3B0IGluICgnLVMnLCAnLS1zdHlsZScpOgogICAgICAgICAgICBvcHRpb25zLmxvY2F0aW9uc3R5bGUgPSBsb2NhdGlvbnMuZ2V0KGFyZy5sb3dlcigpKQogICAgICAgICAgICBpZiBvcHRpb25zLmxvY2F0aW9uc3R5bGUgaXMgTm9uZToKICAgICAgICAgICAgICAgIHVzYWdlKDEsIF8oJ0ludmFsaWQgdmFsdWUgZm9yIC0tc3R5bGU6ICVzJykgJSBhcmcpCiAgICAgICAgZWxpZiBvcHQgaW4gKCctbycsICctLW91dHB1dCcpOgogICAgICAgICAgICBvcHRpb25zLm91dGZpbGUgPSBhcmcKICAgICAgICBlbGlmIG9wdCBpbiAoJy1wJywgJy0tb3V0cHV0LWRpcicpOgogICAgICAgICAgICBvcHRpb25zLm91dHBhdGggPSBhcmcKICAgICAgICBlbGlmIG9wdCBpbiAoJy12JywgJy0tdmVyYm9zZScpOgogICAgICAgICAgICBvcHRpb25zLnZlcmJvc2UgPSAxCiAgICAgICAgZWxpZiBvcHQgaW4gKCctVicsICctLXZlcnNpb24nKToKICAgICAgICAgICAgcHJpbnQoXygncHlnZXR0ZXh0LnB5ICh4Z2V0dGV4dCBmb3IgUHl0aG9uKSAlcycpICUgX192ZXJzaW9uX18pCiAgICAgICAgICAgIHN5cy5leGl0KDApCiAgICAgICAgZWxpZiBvcHQgaW4gKCctdycsICctLXdpZHRoJyk6CiAgICAgICAgICAgIHRyeToKICAgICAgICAgICAgICAgIG9wdGlvbnMud2lkdGggPSBpbnQoYXJnKQogICAgICAgICAgICBleGNlcHQgVmFsdWVFcnJvcjoKICAgICAgICAgICAgICAgIHVzYWdlKDEsIF8oJy0td2lkdGggYXJndW1lbnQgbXVzdCBiZSBhbiBpbnRlZ2VyOiAlcycpICUgYXJnKQogICAgICAgIGVsaWYgb3B0IGluICgnLXgnLCAnLS1leGNsdWRlLWZpbGUnKToKICAgICAgICAgICAgb3B0aW9ucy5leGNsdWRlZmlsZW5hbWUgPSBhcmcKICAgICAgICBlbGlmIG9wdCBpbiAoJy1YJywgJy0tbm8tZG9jc3RyaW5ncycpOgogICAgICAgICAgICBmcCA9IG9wZW4oYXJnKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB3aGlsZSAxOgogICAgICAgICAgICAgICAgICAgIGxpbmUgPSBmcC5yZWFkbGluZSgpCiAgICAgICAgICAgICAgICAgICAgaWYgbm90IGxpbmU6CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrCiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5ub2RvY3N0cmluZ3NbbGluZVs6LTFdXSA9IDEKICAgICAgICAgICAgZmluYWxseToKICAgICAgICAgICAgICAgIGZwLmNsb3NlKCkKCiAgICAjIGNhbGN1bGF0ZSBlc2NhcGVzCiAgICBtYWtlX2VzY2FwZXMobm90IG9wdGlvbnMuZXNjYXBlKQoKICAgICMgY2FsY3VsYXRlIGFsbCBrZXl3b3JkcwogICAgb3B0aW9ucy5rZXl3b3Jkcy5leHRlbmQoZGVmYXVsdF9rZXl3b3JkcykKCiAgICAjIGluaXRpYWxpemUgbGlzdCBvZiBzdHJpbmdzIHRvIGV4Y2x1ZGUKICAgIGlmIG9wdGlvbnMuZXhjbHVkZWZpbGVuYW1lOgogICAgICAgIHRyeToKICAgICAgICAgICAgd2l0aCBvcGVuKG9wdGlvbnMuZXhjbHVkZWZpbGVuYW1lKSBhcyBmcDoKICAgICAgICAgICAgICAgIG9wdGlvbnMudG9leGNsdWRlID0gZnAucmVhZGxpbmVzKCkKICAgICAgICBleGNlcHQgSU9FcnJvcjoKICAgICAgICAgICAgcHJpbnQoXygKICAgICAgICAgICAgICAgICJDYW4ndCByZWFkIC0tZXhjbHVkZS1maWxlOiAlcyIpICUgb3B0aW9ucy5leGNsdWRlZmlsZW5hbWUsIGZpbGU9c3lzLnN0ZGVycikKICAgICAgICAgICAgc3lzLmV4aXQoMSkKICAgIGVsc2U6CiAgICAgICAgb3B0aW9ucy50b2V4Y2x1ZGUgPSBbXQoKICAgICMgcmVzb2x2ZSBhcmdzIHRvIG1vZHVsZSBsaXN0cwogICAgZXhwYW5kZWQgPSBbXQogICAgZm9yIGFyZyBpbiBhcmdzOgogICAgICAgIGlmIGFyZyA9PSAnLSc6CiAgICAgICAgICAgIGV4cGFuZGVkLmFwcGVuZChhcmcpCiAgICAgICAgZWxzZToKICAgICAgICAgICAgZXhwYW5kZWQuZXh0ZW5kKGdldEZpbGVzRm9yTmFtZShhcmcpKQogICAgYXJncyA9IGV4cGFuZGVkCgogICAgIyBzbHVycCB0aHJvdWdoIGFsbCB0aGUgZmlsZXMKICAgIGVhdGVyID0gVG9rZW5FYXRlcihvcHRpb25zKQogICAgZm9yIGZpbGVuYW1lIGluIGFyZ3M6CiAgICAgICAgaWYgZmlsZW5hbWUgPT0gJy0nOgogICAgICAgICAgICBpZiBvcHRpb25zLnZlcmJvc2U6CiAgICAgICAgICAgICAgICBwcmludChfKCdSZWFkaW5nIHN0YW5kYXJkIGlucHV0JykpCiAgICAgICAgICAgIGZwID0gc3lzLnN0ZGluLmJ1ZmZlcgogICAgICAgICAgICBjbG9zZXAgPSAwCiAgICAgICAgZWxzZToKICAgICAgICAgICAgaWYgb3B0aW9ucy52ZXJib3NlOgogICAgICAgICAgICAgICAgcHJpbnQoXygnV29ya2luZyBvbiAlcycpICUgZmlsZW5hbWUpCiAgICAgICAgICAgIGZwID0gb3BlbihmaWxlbmFtZSwgJ3JiJykKICAgICAgICAgICAgY2xvc2VwID0gMQogICAgICAgIHRyeToKICAgICAgICAgICAgZWF0ZXIuc2V0X2ZpbGVuYW1lKGZpbGVuYW1lKQogICAgICAgICAgICB0cnk6CiAgICAgICAgICAgICAgICB0b2tlbnMgPSB0b2tlbml6ZS50b2tlbml6ZShmcC5yZWFkbGluZSkKICAgICAgICAgICAgICAgIGZvciBfdG9rZW4gaW4gdG9rZW5zOgogICAgICAgICAgICAgICAgICAgIGVhdGVyKCpfdG9rZW4pCiAgICAgICAgICAgIGV4Y2VwdCB0b2tlbml6ZS5Ub2tlbkVycm9yIGFzIGU6CiAgICAgICAgICAgICAgICBwcmludCgnJXM6ICVzLCBsaW5lICVkLCBjb2x1bW4gJWQnICUgKAogICAgICAgICAgICAgICAgICAgIGUuYXJnc1swXSwgZmlsZW5hbWUsIGUuYXJnc1sxXVswXSwgZS5hcmdzWzFdWzFdKSwKICAgICAgICAgICAgICAgICAgICBmaWxlPXN5cy5zdGRlcnIpCiAgICAgICAgZmluYWxseToKICAgICAgICAgICAgaWYgY2xvc2VwOgogICAgICAgICAgICAgICAgZnAuY2xvc2UoKQoKICAgICMgd3JpdGUgdGhlIG91dHB1dAogICAgaWYgb3B0aW9ucy5vdXRmaWxlID09ICctJzoKICAgICAgICBmcCA9IHN5cy5zdGRvdXQKICAgICAgICBjbG9zZXAgPSAwCiAgICBlbHNlOgogICAgICAgIGlmIG9wdGlvbnMub3V0cGF0aDoKICAgICAgICAgICAgb3B0aW9ucy5vdXRmaWxlID0gb3MucGF0aC5qb2luKG9wdGlvbnMub3V0cGF0aCwgb3B0aW9ucy5vdXRmaWxlKQogICAgICAgIGZwID0gb3BlbihvcHRpb25zLm91dGZpbGUsICd3JykKICAgICAgICBjbG9zZXAgPSAxCiAgICB0cnk6CiAgICAgICAgZWF0ZXIud3JpdGUoZnApCiAgICBmaW5hbGx5OgogICAgICAgIGlmIGNsb3NlcDoKICAgICAgICAgICAgZnAuY2xvc2UoKQoKCmlmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CiAgICBtYWluKCkKICAgICMgc29tZSBtb3JlIHRlc3Qgc3RyaW5ncwogICAgIyB0aGlzIG9uZSBjcmVhdGVzIGEgd2FybmluZwogICAgXygnKioqIFNlZW4gdW5leHBlY3RlZCB0b2tlbiAiJSh0b2tlbilzIicpICUgeyd0b2tlbic6ICd0ZXN0J30KICAgIF8oJ21vcmUnICd0aGFuJyAnb25lJyAnc3RyaW5nJykK