IyEgL3Vzci9iaW4vZW52IHB5dGhvbg0KIyAtKi0gY29kaW5nOiBpc28tODg1OS0xIC0qLQ0KIyBPcmlnaW5hbGx5IHdyaXR0ZW4gYnkgQmFycnkgV2Fyc2F3IDxiYXJyeUB6b3BlLmNvbT4NCiMNCiMgTWluaW1hbGx5IHBhdGNoZWQgdG8gbWFrZSBpdCBldmVuIG1vcmUgeGdldHRleHQgY29tcGF0aWJsZQ0KIyBieSBQZXRlciBGdW5rIDxwZkBhcnRjb20tZ21iaC5kZT4NCiMNCiMgMjAwMi0xMS0yMiBK/HJnZW4gSGVybWFubiA8amhAd2ViLmRlPg0KIyBBZGRlZCBjaGVja3MgdGhhdCBfKCkgb25seSBjb250YWlucyBzdHJpbmcgbGl0ZXJhbHMsIGFuZA0KIyBjb21tYW5kIGxpbmUgYXJncyBhcmUgcmVzb2x2ZWQgdG8gbW9kdWxlIGxpc3RzLCBpLmUuIHlvdQ0KIyBjYW4gbm93IHBhc3MgYSBmaWxlbmFtZSwgYSBtb2R1bGUgb3IgcGFja2FnZSBuYW1lLCBvciBhDQojIGRpcmVjdG9yeSAoaW5jbHVkaW5nIGdsb2JiaW5nIGNoYXJzLCBpbXBvcnRhbnQgZm9yIFdpbjMyKS4NCiMgTWFkZSBkb2NzdHJpbmcgZml0IGluIDgwIGNoYXJzIHdpZGUgZGlzcGxheXMgdXNpbmcgcHlkb2MuDQojDQoNCiMgZm9yIHNlbGZ0ZXN0aW5nDQp0cnk6DQogICAgaW1wb3J0IGZpbnRsDQogICAgXyA9IGZpbnRsLmdldHRleHQNCmV4Y2VwdCBJbXBvcnRFcnJvcjoNCiAgICBfID0gbGFtYmRhIHM6IHMNCg0KX19kb2NfXyA9IF8oIiIicHlnZXR0ZXh0IC0tIFB5dGhvbiBlcXVpdmFsZW50IG9mIHhnZXR0ZXh0KDEpDQoNCk1hbnkgc3lzdGVtcyAoU29sYXJpcywgTGludXgsIEdudSkgcHJvdmlkZSBleHRlbnNpdmUgdG9vbHMgdGhhdCBlYXNlIHRoZQ0KaW50ZXJuYXRpb25hbGl6YXRpb24gb2YgQyBwcm9ncmFtcy4gTW9zdCBvZiB0aGVzZSB0b29scyBhcmUgaW5kZXBlbmRlbnQgb2YNCnRoZSBwcm9ncmFtbWluZyBsYW5ndWFnZSBhbmQgY2FuIGJlIHVzZWQgZnJvbSB3aXRoaW4gUHl0aG9uIHByb2dyYW1zLg0KTWFydGluIHZvbiBMb2V3aXMnIHdvcmtbMV0gaGVscHMgY29uc2lkZXJhYmx5IGluIHRoaXMgcmVnYXJkLg0KDQpUaGVyZSdzIG9uZSBwcm9ibGVtIHRob3VnaDsgeGdldHRleHQgaXMgdGhlIHByb2dyYW0gdGhhdCBzY2FucyBzb3VyY2UgY29kZQ0KbG9va2luZyBmb3IgbWVzc2FnZSBzdHJpbmdzLCBidXQgaXQgZ3Jva3Mgb25seSBDIChvciBDKyspLiBQeXRob24NCmludHJvZHVjZXMgYSBmZXcgd3JpbmtsZXMsIHN1Y2ggYXMgZHVhbCBxdW90aW5nIGNoYXJhY3RlcnMsIHRyaXBsZSBxdW90ZWQNCnN0cmluZ3MsIGFuZCByYXcgc3RyaW5ncy4geGdldHRleHQgdW5kZXJzdGFuZHMgbm9uZSBvZiB0aGlzLg0KDQpFbnRlciBweWdldHRleHQsIHdoaWNoIHVzZXMgUHl0aG9uJ3Mgc3RhbmRhcmQgdG9rZW5pemUgbW9kdWxlIHRvIHNjYW4NClB5dGhvbiBzb3VyY2UgY29kZSwgZ2VuZXJhdGluZyAucG90IGZpbGVzIGlkZW50aWNhbCB0byB3aGF0IEdOVSB4Z2V0dGV4dFsyXQ0KZ2VuZXJhdGVzIGZvciBDIGFuZCBDKysgY29kZS4gRnJvbSB0aGVyZSwgdGhlIHN0YW5kYXJkIEdOVSB0b29scyBjYW4gYmUNCnVzZWQuDQoNCkEgd29yZCBhYm91dCBtYXJraW5nIFB5dGhvbiBzdHJpbmdzIGFzIGNhbmRpZGF0ZXMgZm9yIHRyYW5zbGF0aW9uLiBHTlUNCnhnZXR0ZXh0IHJlY29nbml6ZXMgdGhlIGZvbGxvd2luZyBrZXl3b3JkczogZ2V0dGV4dCwgZGdldHRleHQsIGRjZ2V0dGV4dCwNCmFuZCBnZXR0ZXh0X25vb3AuIEJ1dCB0aG9zZSBjYW4gYmUgYSBsb3Qgb2YgdGV4dCB0byBpbmNsdWRlIGFsbCBvdmVyIHlvdXINCmNvZGUuIEMgYW5kIEMrKyBoYXZlIGEgdHJpY2s6IHRoZXkgdXNlIHRoZSBDIHByZXByb2Nlc3Nvci4gTW9zdA0KaW50ZXJuYXRpb25hbGl6ZWQgQyBzb3VyY2UgaW5jbHVkZXMgYSAjZGVmaW5lIGZvciBnZXR0ZXh0KCkgdG8gXygpIHNvIHRoYXQNCndoYXQgaGFzIHRvIGJlIHdyaXR0ZW4gaW4gdGhlIHNvdXJjZSBpcyBtdWNoIGxlc3MuIFRodXMgdGhlc2UgYXJlIGJvdGgNCnRyYW5zbGF0YWJsZSBzdHJpbmdzOg0KDQogICAgZ2V0dGV4dCgiVHJhbnNsYXRhYmxlIFN0cmluZyIpDQogICAgXygiVHJhbnNsYXRhYmxlIFN0cmluZyIpDQoNClB5dGhvbiBvZiBjb3Vyc2UgaGFzIG5vIHByZXByb2Nlc3NvciBzbyB0aGlzIGRvZXNuJ3Qgd29yayBzbyB3ZWxsLiAgVGh1cywNCnB5Z2V0dGV4dCBzZWFyY2hlcyBvbmx5IGZvciBfKCkgYnkgZGVmYXVsdCwgYnV0IHNlZSB0aGUgLWsvLS1rZXl3b3JkIGZsYWcNCmJlbG93IGZvciBob3cgdG8gYXVnbWVudCB0aGlzLg0KDQogWzFdIGh0dHA6Ly93d3cucHl0aG9uLm9yZy93b3Jrc2hvcHMvMTk5Ny0xMC9wcm9jZWVkaW5ncy9sb2V3aXMuaHRtbA0KIFsyXSBodHRwOi8vd3d3LmdudS5vcmcvc29mdHdhcmUvZ2V0dGV4dC9nZXR0ZXh0Lmh0bWwNCg0KTk9URTogcHlnZXR0ZXh0IGF0dGVtcHRzIHRvIGJlIG9wdGlvbiBhbmQgZmVhdHVyZSBjb21wYXRpYmxlIHdpdGggR05VDQp4Z2V0dGV4dCB3aGVyZSBldmVyIHBvc3NpYmxlLiBIb3dldmVyIHNvbWUgb3B0aW9ucyBhcmUgc3RpbGwgbWlzc2luZyBvciBhcmUNCm5vdCBmdWxseSBpbXBsZW1lbnRlZC4gQWxzbywgeGdldHRleHQncyB1c2Ugb2YgY29tbWFuZCBsaW5lIHN3aXRjaGVzIHdpdGgNCm9wdGlvbiBhcmd1bWVudHMgaXMgYnJva2VuLCBhbmQgaW4gdGhlc2UgY2FzZXMsIHB5Z2V0dGV4dCBqdXN0IGRlZmluZXMNCmFkZGl0aW9uYWwgc3dpdGNoZXMuDQoNClVzYWdlOiBweWdldHRleHQgW29wdGlvbnNdIGlucHV0ZmlsZSAuLi4NCg0KT3B0aW9uczoNCg0KICAgIC1hDQogICAgLS1leHRyYWN0LWFsbA0KICAgICAgICBFeHRyYWN0IGFsbCBzdHJpbmdzLg0KDQogICAgLWQgbmFtZQ0KICAgIC0tZGVmYXVsdC1kb21haW49bmFtZQ0KICAgICAgICBSZW5hbWUgdGhlIGRlZmF1bHQgb3V0cHV0IGZpbGUgZnJvbSBtZXNzYWdlcy5wb3QgdG8gbmFtZS5wb3QuDQoNCiAgICAtRQ0KICAgIC0tZXNjYXBlDQogICAgICAgIFJlcGxhY2Ugbm9uLUFTQ0lJIGNoYXJhY3RlcnMgd2l0aCBvY3RhbCBlc2NhcGUgc2VxdWVuY2VzLg0KDQogICAgLUQNCiAgICAtLWRvY3N0cmluZ3MNCiAgICAgICAgRXh0cmFjdCBtb2R1bGUsIGNsYXNzLCBtZXRob2QsIGFuZCBmdW5jdGlvbiBkb2NzdHJpbmdzLiAgVGhlc2UgZG8NCiAgICAgICAgbm90IG5lZWQgdG8gYmUgd3JhcHBlZCBpbiBfKCkgbWFya2VycywgYW5kIGluIGZhY3QgY2Fubm90IGJlIGZvcg0KICAgICAgICBQeXRob24gdG8gY29uc2lkZXIgdGhlbSBkb2NzdHJpbmdzLiAoU2VlIGFsc28gdGhlIC1YIG9wdGlvbikuDQoNCiAgICAtaA0KICAgIC0taGVscA0KICAgICAgICBQcmludCB0aGlzIGhlbHAgbWVzc2FnZSBhbmQgZXhpdC4NCg0KICAgIC1rIHdvcmQNCiAgICAtLWtleXdvcmQ9d29yZA0KICAgICAgICBLZXl3b3JkcyB0byBsb29rIGZvciBpbiBhZGRpdGlvbiB0byB0aGUgZGVmYXVsdCBzZXQsIHdoaWNoIGFyZToNCiAgICAgICAgJShERUZBVUxUS0VZV09SRFMpcw0KDQogICAgICAgIFlvdSBjYW4gaGF2ZSBtdWx0aXBsZSAtayBmbGFncyBvbiB0aGUgY29tbWFuZCBsaW5lLg0KDQogICAgLUsNCiAgICAtLW5vLWRlZmF1bHQta2V5d29yZHMNCiAgICAgICAgRGlzYWJsZSB0aGUgZGVmYXVsdCBzZXQgb2Yga2V5d29yZHMgKHNlZSBhYm92ZSkuICBBbnkga2V5d29yZHMNCiAgICAgICAgZXhwbGljaXRseSBhZGRlZCB3aXRoIHRoZSAtay8tLWtleXdvcmQgb3B0aW9uIGFyZSBzdGlsbCByZWNvZ25pemVkLg0KDQogICAgLS1uby1sb2NhdGlvbg0KICAgICAgICBEbyBub3Qgd3JpdGUgZmlsZW5hbWUvbGluZW5vIGxvY2F0aW9uIGNvbW1lbnRzLg0KDQogICAgLW4NCiAgICAtLWFkZC1sb2NhdGlvbg0KICAgICAgICBXcml0ZSBmaWxlbmFtZS9saW5lbm8gbG9jYXRpb24gY29tbWVudHMgaW5kaWNhdGluZyB3aGVyZSBlYWNoDQogICAgICAgIGV4dHJhY3RlZCBzdHJpbmcgaXMgZm91bmQgaW4gdGhlIHNvdXJjZS4gIFRoZXNlIGxpbmVzIGFwcGVhciBiZWZvcmUNCiAgICAgICAgZWFjaCBtc2dpZC4gIFRoZSBzdHlsZSBvZiBjb21tZW50cyBpcyBjb250cm9sbGVkIGJ5IHRoZSAtUy8tLXN0eWxlDQogICAgICAgIG9wdGlvbi4gIFRoaXMgaXMgdGhlIGRlZmF1bHQuDQoNCiAgICAtbyBmaWxlbmFtZQ0KICAgIC0tb3V0cHV0PWZpbGVuYW1lDQogICAgICAgIFJlbmFtZSB0aGUgZGVmYXVsdCBvdXRwdXQgZmlsZSBmcm9tIG1lc3NhZ2VzLnBvdCB0byBmaWxlbmFtZS4gIElmDQogICAgICAgIGZpbGVuYW1lIGlzIGAtJyB0aGVuIHRoZSBvdXRwdXQgaXMgc2VudCB0byBzdGFuZGFyZCBvdXQuDQoNCiAgICAtcCBkaXINCiAgICAtLW91dHB1dC1kaXI9ZGlyDQogICAgICAgIE91dHB1dCBmaWxlcyB3aWxsIGJlIHBsYWNlZCBpbiBkaXJlY3RvcnkgZGlyLg0KDQogICAgLVMgc3R5bGVuYW1lDQogICAgLS1zdHlsZSBzdHlsZW5hbWUNCiAgICAgICAgU3BlY2lmeSB3aGljaCBzdHlsZSB0byB1c2UgZm9yIGxvY2F0aW9uIGNvbW1lbnRzLiAgVHdvIHN0eWxlcyBhcmUNCiAgICAgICAgc3VwcG9ydGVkOg0KDQogICAgICAgIFNvbGFyaXMgICMgRmlsZTogZmlsZW5hbWUsIGxpbmU6IGxpbmUtbnVtYmVyDQogICAgICAgIEdOVSAgICAgICM6IGZpbGVuYW1lOmxpbmUNCg0KICAgICAgICBUaGUgc3R5bGUgbmFtZSBpcyBjYXNlIGluc2Vuc2l0aXZlLiAgR05VIHN0eWxlIGlzIHRoZSBkZWZhdWx0Lg0KDQogICAgLXYNCiAgICAtLXZlcmJvc2UNCiAgICAgICAgUHJpbnQgdGhlIG5hbWVzIG9mIHRoZSBmaWxlcyBiZWluZyBwcm9jZXNzZWQuDQoNCiAgICAtVg0KICAgIC0tdmVyc2lvbg0KICAgICAgICBQcmludCB0aGUgdmVyc2lvbiBvZiBweWdldHRleHQgYW5kIGV4aXQuDQoNCiAgICAtdyBjb2x1bW5zDQogICAgLS13aWR0aD1jb2x1bW5zDQogICAgICAgIFNldCB3aWR0aCBvZiBvdXRwdXQgdG8gY29sdW1ucy4NCg0KICAgIC14IGZpbGVuYW1lDQogICAgLS1leGNsdWRlLWZpbGU9ZmlsZW5hbWUNCiAgICAgICAgU3BlY2lmeSBhIGZpbGUgdGhhdCBjb250YWlucyBhIGxpc3Qgb2Ygc3RyaW5ncyB0aGF0IGFyZSBub3QgYmUNCiAgICAgICAgZXh0cmFjdGVkIGZyb20gdGhlIGlucHV0IGZpbGVzLiAgRWFjaCBzdHJpbmcgdG8gYmUgZXhjbHVkZWQgbXVzdA0KICAgICAgICBhcHBlYXIgb24gYSBsaW5lIGJ5IGl0c2VsZiBpbiB0aGUgZmlsZS4NCg0KICAgIC1YIGZpbGVuYW1lDQogICAgLS1uby1kb2NzdHJpbmdzPWZpbGVuYW1lDQogICAgICAgIFNwZWNpZnkgYSBmaWxlIHRoYXQgY29udGFpbnMgYSBsaXN0IG9mIGZpbGVzIChvbmUgcGVyIGxpbmUpIHRoYXQNCiAgICAgICAgc2hvdWxkIG5vdCBoYXZlIHRoZWlyIGRvY3N0cmluZ3MgZXh0cmFjdGVkLiAgVGhpcyBpcyBvbmx5IHVzZWZ1bCBpbg0KICAgICAgICBjb25qdW5jdGlvbiB3aXRoIHRoZSAtRCBvcHRpb24gYWJvdmUuDQoNCklmIGBpbnB1dGZpbGUnIGlzIC0sIHN0YW5kYXJkIGlucHV0IGlzIHJlYWQuDQoiIiIpDQoNCmltcG9ydCBvcw0KaW1wb3J0IGltcA0KaW1wb3J0IHN5cw0KaW1wb3J0IGdsb2INCmltcG9ydCB0aW1lDQppbXBvcnQgZ2V0b3B0DQppbXBvcnQgdG9rZW4NCmltcG9ydCB0b2tlbml6ZQ0KaW1wb3J0IG9wZXJhdG9yDQoNCl9fdmVyc2lvbl9fID0gJzEuNScNCg0KZGVmYXVsdF9rZXl3b3JkcyA9IFsnXyddDQpERUZBVUxUS0VZV09SRFMgPSAnLCAnLmpvaW4oZGVmYXVsdF9rZXl3b3JkcykNCg0KRU1QVFlTVFJJTkcgPSAnJw0KDQoNCgwNCiMgVGhlIG5vcm1hbCBwb3QtZmlsZSBoZWFkZXIuIG1zZ21lcmdlIGFuZCBFbWFjcydzIHBvLW1vZGUgd29yayBiZXR0ZXIgaWYgaXQncw0KIyB0aGVyZS4NCnBvdF9oZWFkZXIgPSBfKCcnJ1wNCiMgU09NRSBERVNDUklQVElWRSBUSVRMRS4NCiMgQ29weXJpZ2h0IChDKSBZRUFSIE9SR0FOSVpBVElPTg0KIyBGSVJTVCBBVVRIT1IgPEVNQUlMQEFERFJFU1M+LCBZRUFSLg0KIw0KbXNnaWQgIiINCm1zZ3N0ciAiIg0KIlByb2plY3QtSWQtVmVyc2lvbjogUEFDS0FHRSBWRVJTSU9OXFxuIg0KIlBPVC1DcmVhdGlvbi1EYXRlOiAlKHRpbWUpc1xcbiINCiJQTy1SZXZpc2lvbi1EYXRlOiBZRUFSLU1PLURBIEhPOk1JK1pPTkVcXG4iDQoiTGFzdC1UcmFuc2xhdG9yOiBGVUxMIE5BTUUgPEVNQUlMQEFERFJFU1M+XFxuIg0KIkxhbmd1YWdlLVRlYW06IExBTkdVQUdFIDxMTEBsaS5vcmc+XFxuIg0KIk1JTUUtVmVyc2lvbjogMS4wXFxuIg0KIkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgY2hhcnNldD1DSEFSU0VUXFxuIg0KIkNvbnRlbnQtVHJhbnNmZXItRW5jb2Rpbmc6IEVOQ09ESU5HXFxuIg0KIkdlbmVyYXRlZC1CeTogcHlnZXR0ZXh0LnB5ICUodmVyc2lvbilzXFxuIg0KDQonJycpDQoNCgwNCmRlZiB1c2FnZShjb2RlLCBtc2c9JycpOg0KICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIF9fZG9jX18gJSBnbG9iYWxzKCkNCiAgICBpZiBtc2c6DQogICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIG1zZw0KICAgIHN5cy5leGl0KGNvZGUpDQoNCg0KDA0KZXNjYXBlcyA9IFtdDQoNCmRlZiBtYWtlX2VzY2FwZXMocGFzc19pc284ODU5KToNCiAgICBnbG9iYWwgZXNjYXBlcw0KICAgIGlmIHBhc3NfaXNvODg1OToNCiAgICAgICAgIyBBbGxvdyBpc28tODg1OSBjaGFyYWN0ZXJzIHRvIHBhc3MgdGhyb3VnaCBzbyB0aGF0IGUuZy4gJ21zZ2lkDQogICAgICAgICMgIkj2aGUiJyB3b3VsZCByZXN1bHQgbm90IHJlc3VsdCBpbiAnbXNnaWQgIkhcMzY2aGUiJy4gIE90aGVyd2lzZSB3ZQ0KICAgICAgICAjIGVzY2FwZSBhbnkgY2hhcmFjdGVyIG91dHNpZGUgdGhlIDMyLi4xMjYgcmFuZ2UuDQogICAgICAgIG1vZCA9IDEyOA0KICAgIGVsc2U6DQogICAgICAgIG1vZCA9IDI1Ng0KICAgIGZvciBpIGluIHJhbmdlKDI1Nik6DQogICAgICAgIGlmIDMyIDw9IChpICUgbW9kKSA8PSAxMjY6DQogICAgICAgICAgICBlc2NhcGVzLmFwcGVuZChjaHIoaSkpDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICBlc2NhcGVzLmFwcGVuZCgiXFwlMDNvIiAlIGkpDQogICAgZXNjYXBlc1tvcmQoJ1xcJyldID0gJ1xcXFwnDQogICAgZXNjYXBlc1tvcmQoJ1x0JyldID0gJ1xcdCcNCiAgICBlc2NhcGVzW29yZCgnXHInKV0gPSAnXFxyJw0KICAgIGVzY2FwZXNbb3JkKCdcbicpXSA9ICdcXG4nDQogICAgZXNjYXBlc1tvcmQoJ1wiJyldID0gJ1xcIicNCg0KDQpkZWYgZXNjYXBlKHMpOg0KICAgIGdsb2JhbCBlc2NhcGVzDQogICAgcyA9IGxpc3QocykNCiAgICBmb3IgaSBpbiByYW5nZShsZW4ocykpOg0KICAgICAgICBzW2ldID0gZXNjYXBlc1tvcmQoc1tpXSldDQogICAgcmV0dXJuIEVNUFRZU1RSSU5HLmpvaW4ocykNCg0KDQpkZWYgc2FmZV9ldmFsKHMpOg0KICAgICMgdW53cmFwIHF1b3Rlcywgc2FmZWx5DQogICAgcmV0dXJuIGV2YWwocywgeydfX2J1aWx0aW5zX18nOnt9fSwge30pDQoNCg0KZGVmIG5vcm1hbGl6ZShzKToNCiAgICAjIFRoaXMgY29udmVydHMgdGhlIHZhcmlvdXMgUHl0aG9uIHN0cmluZyB0eXBlcyBpbnRvIGEgZm9ybWF0IHRoYXQgaXMNCiAgICAjIGFwcHJvcHJpYXRlIGZvciAucG8gZmlsZXMsIG5hbWVseSBtdWNoIGNsb3NlciB0byBDIHN0eWxlLg0KICAgIGxpbmVzID0gcy5zcGxpdCgnXG4nKQ0KICAgIGlmIGxlbihsaW5lcykgPT0gMToNCiAgICAgICAgcyA9ICciJyArIGVzY2FwZShzKSArICciJw0KICAgIGVsc2U6DQogICAgICAgIGlmIG5vdCBsaW5lc1stMV06DQogICAgICAgICAgICBkZWwgbGluZXNbLTFdDQogICAgICAgICAgICBsaW5lc1stMV0gPSBsaW5lc1stMV0gKyAnXG4nDQogICAgICAgIGZvciBpIGluIHJhbmdlKGxlbihsaW5lcykpOg0KICAgICAgICAgICAgbGluZXNbaV0gPSBlc2NhcGUobGluZXNbaV0pDQogICAgICAgIGxpbmV0ZXJtID0gJ1xcbiJcbiInDQogICAgICAgIHMgPSAnIiJcbiInICsgbGluZXRlcm0uam9pbihsaW5lcykgKyAnIicNCiAgICByZXR1cm4gcw0KDQoMDQpkZWYgY29udGFpbnNBbnkoc3RyLCBzZXQpOg0KICAgICIiIkNoZWNrIHdoZXRoZXIgJ3N0cicgY29udGFpbnMgQU5ZIG9mIHRoZSBjaGFycyBpbiAnc2V0JyIiIg0KICAgIHJldHVybiAxIGluIFtjIGluIHN0ciBmb3IgYyBpbiBzZXRdDQoNCg0KZGVmIF92aXNpdF9weWZpbGVzKGxpc3QsIGRpcm5hbWUsIG5hbWVzKToNCiAgICAiIiJIZWxwZXIgZm9yIGdldEZpbGVzRm9yTmFtZSgpLiIiIg0KICAgICMgZ2V0IGV4dGVuc2lvbiBmb3IgcHl0aG9uIHNvdXJjZSBmaWxlcw0KICAgIGlmIG5vdCBnbG9iYWxzKCkuaGFzX2tleSgnX3B5X2V4dCcpOg0KICAgICAgICBnbG9iYWwgX3B5X2V4dA0KICAgICAgICBfcHlfZXh0ID0gW3RyaXBsZVswXSBmb3IgdHJpcGxlIGluIGltcC5nZXRfc3VmZml4ZXMoKQ0KICAgICAgICAgICAgICAgICAgIGlmIHRyaXBsZVsyXSA9PSBpbXAuUFlfU09VUkNFXVswXQ0KDQogICAgIyBkb24ndCByZWN1cnNlIGludG8gQ1ZTIGRpcmVjdG9yaWVzDQogICAgaWYgJ0NWUycgaW4gbmFtZXM6DQogICAgICAgIG5hbWVzLnJlbW92ZSgnQ1ZTJykNCg0KICAgICMgYWRkIGFsbCAqLnB5IGZpbGVzIHRvIGxpc3QNCiAgICBsaXN0LmV4dGVuZCgNCiAgICAgICAgW29zLnBhdGguam9pbihkaXJuYW1lLCBmaWxlKSBmb3IgZmlsZSBpbiBuYW1lcw0KICAgICAgICAgaWYgb3MucGF0aC5zcGxpdGV4dChmaWxlKVsxXSA9PSBfcHlfZXh0XQ0KICAgICAgICApDQoNCg0KZGVmIF9nZXRfbW9kcGtnX3BhdGgoZG90dGVkX25hbWUsIHBhdGhsaXN0PU5vbmUpOg0KICAgICIiIkdldCB0aGUgZmlsZXN5c3RlbSBwYXRoIGZvciBhIG1vZHVsZSBvciBhIHBhY2thZ2UuDQoNCiAgICBSZXR1cm4gdGhlIGZpbGUgc3lzdGVtIHBhdGggdG8gYSBmaWxlIGZvciBhIG1vZHVsZSwgYW5kIHRvIGEgZGlyZWN0b3J5IGZvcg0KICAgIGEgcGFja2FnZS4gUmV0dXJuIE5vbmUgaWYgdGhlIG5hbWUgaXMgbm90IGZvdW5kLCBvciBpcyBhIGJ1aWx0aW4gb3INCiAgICBleHRlbnNpb24gbW9kdWxlLg0KICAgICIiIg0KICAgICMgc3BsaXQgb2ZmIHRvcC1tb3N0IG5hbWUNCiAgICBwYXJ0cyA9IGRvdHRlZF9uYW1lLnNwbGl0KCcuJywgMSkNCg0KICAgIGlmIGxlbihwYXJ0cykgPiAxOg0KICAgICAgICAjIHdlIGhhdmUgYSBkb3R0ZWQgcGF0aCwgaW1wb3J0IHRvcC1sZXZlbCBwYWNrYWdlDQogICAgICAgIHRyeToNCiAgICAgICAgICAgIGZpbGUsIHBhdGhuYW1lLCBkZXNjcmlwdGlvbiA9IGltcC5maW5kX21vZHVsZShwYXJ0c1swXSwgcGF0aGxpc3QpDQogICAgICAgICAgICBpZiBmaWxlOiBmaWxlLmNsb3NlKCkNCiAgICAgICAgZXhjZXB0IEltcG9ydEVycm9yOg0KICAgICAgICAgICAgcmV0dXJuIE5vbmUNCg0KICAgICAgICAjIGNoZWNrIGlmIGl0J3MgaW5kZWVkIGEgcGFja2FnZQ0KICAgICAgICBpZiBkZXNjcmlwdGlvblsyXSA9PSBpbXAuUEtHX0RJUkVDVE9SWToNCiAgICAgICAgICAgICMgcmVjdXJzaXZlbHkgaGFuZGxlIHRoZSByZW1haW5pbmcgbmFtZSBwYXJ0cw0KICAgICAgICAgICAgcGF0aG5hbWUgPSBfZ2V0X21vZHBrZ19wYXRoKHBhcnRzWzFdLCBbcGF0aG5hbWVdKQ0KICAgICAgICBlbHNlOg0KICAgICAgICAgICAgcGF0aG5hbWUgPSBOb25lDQogICAgZWxzZToNCiAgICAgICAgIyBwbGFpbiBuYW1lDQogICAgICAgIHRyeToNCiAgICAgICAgICAgIGZpbGUsIHBhdGhuYW1lLCBkZXNjcmlwdGlvbiA9IGltcC5maW5kX21vZHVsZSgNCiAgICAgICAgICAgICAgICBkb3R0ZWRfbmFtZSwgcGF0aGxpc3QpDQogICAgICAgICAgICBpZiBmaWxlOg0KICAgICAgICAgICAgICAgIGZpbGUuY2xvc2UoKQ0KICAgICAgICAgICAgaWYgZGVzY3JpcHRpb25bMl0gbm90IGluIFtpbXAuUFlfU09VUkNFLCBpbXAuUEtHX0RJUkVDVE9SWV06DQogICAgICAgICAgICAgICAgcGF0aG5hbWUgPSBOb25lDQogICAgICAgIGV4Y2VwdCBJbXBvcnRFcnJvcjoNCiAgICAgICAgICAgIHBhdGhuYW1lID0gTm9uZQ0KDQogICAgcmV0dXJuIHBhdGhuYW1lDQoNCg0KZGVmIGdldEZpbGVzRm9yTmFtZShuYW1lKToNCiAgICAiIiJHZXQgYSBsaXN0IG9mIG1vZHVsZSBmaWxlcyBmb3IgYSBmaWxlbmFtZSwgYSBtb2R1bGUgb3IgcGFja2FnZSBuYW1lLA0KICAgIG9yIGEgZGlyZWN0b3J5Lg0KICAgICIiIg0KICAgIGlmIG5vdCBvcy5wYXRoLmV4aXN0cyhuYW1lKToNCiAgICAgICAgIyBjaGVjayBmb3IgZ2xvYiBjaGFycw0KICAgICAgICBpZiBjb250YWluc0FueShuYW1lLCAiKj9bXSIpOg0KICAgICAgICAgICAgZmlsZXMgPSBnbG9iLmdsb2IobmFtZSkNCiAgICAgICAgICAgIGxpc3QgPSBbXQ0KICAgICAgICAgICAgZm9yIGZpbGUgaW4gZmlsZXM6DQogICAgICAgICAgICAgICAgbGlzdC5leHRlbmQoZ2V0RmlsZXNGb3JOYW1lKGZpbGUpKQ0KICAgICAgICAgICAgcmV0dXJuIGxpc3QNCg0KICAgICAgICAjIHRyeSB0byBmaW5kIG1vZHVsZSBvciBwYWNrYWdlDQogICAgICAgIG5hbWUgPSBfZ2V0X21vZHBrZ19wYXRoKG5hbWUpDQogICAgICAgIGlmIG5vdCBuYW1lOg0KICAgICAgICAgICAgcmV0dXJuIFtdDQoNCiAgICBpZiBvcy5wYXRoLmlzZGlyKG5hbWUpOg0KICAgICAgICAjIGZpbmQgYWxsIHB5dGhvbiBmaWxlcyBpbiBkaXJlY3RvcnkNCiAgICAgICAgbGlzdCA9IFtdDQogICAgICAgIG9zLnBhdGgud2FsayhuYW1lLCBfdmlzaXRfcHlmaWxlcywgbGlzdCkNCiAgICAgICAgcmV0dXJuIGxpc3QNCiAgICBlbGlmIG9zLnBhdGguZXhpc3RzKG5hbWUpOg0KICAgICAgICAjIGEgc2luZ2xlIGZpbGUNCiAgICAgICAgcmV0dXJuIFtuYW1lXQ0KDQogICAgcmV0dXJuIFtdDQoNCgwNCmNsYXNzIFRva2VuRWF0ZXI6DQogICAgZGVmIF9faW5pdF9fKHNlbGYsIG9wdGlvbnMpOg0KICAgICAgICBzZWxmLl9fb3B0aW9ucyA9IG9wdGlvbnMNCiAgICAgICAgc2VsZi5fX21lc3NhZ2VzID0ge30NCiAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3dhaXRpbmcNCiAgICAgICAgc2VsZi5fX2RhdGEgPSBbXQ0KICAgICAgICBzZWxmLl9fbGluZW5vID0gLTENCiAgICAgICAgc2VsZi5fX2ZyZXNobW9kdWxlID0gMQ0KICAgICAgICBzZWxmLl9fY3VyZmlsZSA9IE5vbmUNCg0KICAgIGRlZiBfX2NhbGxfXyhzZWxmLCB0dHlwZSwgdHN0cmluZywgc3R1cCwgZXR1cCwgbGluZSk6DQogICAgICAgICMgZGlzcGF0Y2gNCiMjICAgICAgICBpbXBvcnQgdG9rZW4NCiMjICAgICAgICBwcmludCA+PiBzeXMuc3RkZXJyLCAndHR5cGU6JywgdG9rZW4udG9rX25hbWVbdHR5cGVdLCBcDQojIyAgICAgICAgICAgICAgJ3RzdHJpbmc6JywgdHN0cmluZw0KICAgICAgICBzZWxmLl9fc3RhdGUodHR5cGUsIHRzdHJpbmcsIHN0dXBbMF0pDQoNCiAgICBkZWYgX193YWl0aW5nKHNlbGYsIHR0eXBlLCB0c3RyaW5nLCBsaW5lbm8pOg0KICAgICAgICBvcHRzID0gc2VsZi5fX29wdGlvbnMNCiAgICAgICAgIyBEbyBkb2NzdHJpbmcgZXh0cmFjdGlvbnMsIGlmIGVuYWJsZWQNCiAgICAgICAgaWYgb3B0cy5kb2NzdHJpbmdzIGFuZCBub3Qgb3B0cy5ub2RvY3N0cmluZ3MuZ2V0KHNlbGYuX19jdXJmaWxlKToNCiAgICAgICAgICAgICMgbW9kdWxlIGRvY3N0cmluZz8NCiAgICAgICAgICAgIGlmIHNlbGYuX19mcmVzaG1vZHVsZToNCiAgICAgICAgICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5TVFJJTkc6DQogICAgICAgICAgICAgICAgICAgIHNlbGYuX19hZGRlbnRyeShzYWZlX2V2YWwodHN0cmluZyksIGxpbmVubywgaXNkb2NzdHJpbmc9MSkNCiAgICAgICAgICAgICAgICAgICAgc2VsZi5fX2ZyZXNobW9kdWxlID0gMA0KICAgICAgICAgICAgICAgIGVsaWYgdHR5cGUgbm90IGluICh0b2tlbml6ZS5DT01NRU5ULCB0b2tlbml6ZS5OTCk6DQogICAgICAgICAgICAgICAgICAgIHNlbGYuX19mcmVzaG1vZHVsZSA9IDANCiAgICAgICAgICAgICAgICByZXR1cm4NCiAgICAgICAgICAgICMgY2xhc3MgZG9jc3RyaW5nPw0KICAgICAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuTkFNRSBhbmQgdHN0cmluZyBpbiAoJ2NsYXNzJywgJ2RlZicpOg0KICAgICAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX19zdWl0ZXNlZW4NCiAgICAgICAgICAgICAgICByZXR1cm4NCiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuTkFNRSBhbmQgdHN0cmluZyBpbiBvcHRzLmtleXdvcmRzOg0KICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX2tleXdvcmRzZWVuDQoNCiAgICBkZWYgX19zdWl0ZXNlZW4oc2VsZiwgdHR5cGUsIHRzdHJpbmcsIGxpbmVubyk6DQogICAgICAgICMgaWdub3JlIGFueXRoaW5nIHVudGlsIHdlIHNlZSB0aGUgY29sb24NCiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuT1AgYW5kIHRzdHJpbmcgPT0gJzonOg0KICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3N1aXRlZG9jc3RyaW5nDQoNCiAgICBkZWYgX19zdWl0ZWRvY3N0cmluZyhzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToNCiAgICAgICAgIyBpZ25vcmUgYW55IGludGVydmVuaW5nIG5vaXNlDQogICAgICAgIGlmIHR0eXBlID09IHRva2VuaXplLlNUUklORzoNCiAgICAgICAgICAgIHNlbGYuX19hZGRlbnRyeShzYWZlX2V2YWwodHN0cmluZyksIGxpbmVubywgaXNkb2NzdHJpbmc9MSkNCiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nDQogICAgICAgIGVsaWYgdHR5cGUgbm90IGluICh0b2tlbml6ZS5ORVdMSU5FLCB0b2tlbml6ZS5JTkRFTlQsDQogICAgICAgICAgICAgICAgICAgICAgICAgICB0b2tlbml6ZS5DT01NRU5UKToNCiAgICAgICAgICAgICMgdGhlcmUgd2FzIG5vIGNsYXNzIGRvY3N0cmluZw0KICAgICAgICAgICAgc2VsZi5fX3N0YXRlID0gc2VsZi5fX3dhaXRpbmcNCg0KICAgIGRlZiBfX2tleXdvcmRzZWVuKHNlbGYsIHR0eXBlLCB0c3RyaW5nLCBsaW5lbm8pOg0KICAgICAgICBpZiB0dHlwZSA9PSB0b2tlbml6ZS5PUCBhbmQgdHN0cmluZyA9PSAnKCc6DQogICAgICAgICAgICBzZWxmLl9fZGF0YSA9IFtdDQogICAgICAgICAgICBzZWxmLl9fbGluZW5vID0gbGluZW5vDQogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fb3BlbnNlZW4NCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nDQoNCiAgICBkZWYgX19vcGVuc2VlbihzZWxmLCB0dHlwZSwgdHN0cmluZywgbGluZW5vKToNCiAgICAgICAgaWYgdHR5cGUgPT0gdG9rZW5pemUuT1AgYW5kIHRzdHJpbmcgPT0gJyknOg0KICAgICAgICAgICAgIyBXZSd2ZSBzZWVuIHRoZSBsYXN0IG9mIHRoZSB0cmFuc2xhdGFibGUgc3RyaW5ncy4gIFJlY29yZCB0aGUNCiAgICAgICAgICAgICMgbGluZSBudW1iZXIgb2YgdGhlIGZpcnN0IGxpbmUgb2YgdGhlIHN0cmluZ3MgYW5kIHVwZGF0ZSB0aGUgbGlzdA0KICAgICAgICAgICAgIyBvZiBtZXNzYWdlcyBzZWVuLiAgUmVzZXQgc3RhdGUgZm9yIHRoZSBuZXh0IGJhdGNoLiAgSWYgdGhlcmUNCiAgICAgICAgICAgICMgd2VyZSBubyBzdHJpbmdzIGluc2lkZSBfKCksIHRoZW4ganVzdCBpZ25vcmUgdGhpcyBlbnRyeS4NCiAgICAgICAgICAgIGlmIHNlbGYuX19kYXRhOg0KICAgICAgICAgICAgICAgIHNlbGYuX19hZGRlbnRyeShFTVBUWVNUUklORy5qb2luKHNlbGYuX19kYXRhKSkNCiAgICAgICAgICAgIHNlbGYuX19zdGF0ZSA9IHNlbGYuX193YWl0aW5nDQogICAgICAgIGVsaWYgdHR5cGUgPT0gdG9rZW5pemUuU1RSSU5HOg0KICAgICAgICAgICAgc2VsZi5fX2RhdGEuYXBwZW5kKHNhZmVfZXZhbCh0c3RyaW5nKSkNCiAgICAgICAgZWxpZiB0dHlwZSBub3QgaW4gW3Rva2VuaXplLkNPTU1FTlQsIHRva2VuLklOREVOVCwgdG9rZW4uREVERU5ULA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgdG9rZW4uTkVXTElORSwgdG9rZW5pemUuTkxdOg0KICAgICAgICAgICAgIyB3YXJuIGlmIHdlIHNlZSBhbnl0aGluZyBlbHNlIHRoYW4gU1RSSU5HIG9yIHdoaXRlc3BhY2UNCiAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIF8oDQogICAgICAgICAgICAgICAgJyoqKiAlKGZpbGUpczolKGxpbmVubylzOiBTZWVuIHVuZXhwZWN0ZWQgdG9rZW4gIiUodG9rZW4pcyInDQogICAgICAgICAgICAgICAgKSAlIHsNCiAgICAgICAgICAgICAgICAndG9rZW4nOiB0c3RyaW5nLA0KICAgICAgICAgICAgICAgICdmaWxlJzogc2VsZi5fX2N1cmZpbGUsDQogICAgICAgICAgICAgICAgJ2xpbmVubyc6IHNlbGYuX19saW5lbm8NCiAgICAgICAgICAgICAgICB9DQogICAgICAgICAgICBzZWxmLl9fc3RhdGUgPSBzZWxmLl9fd2FpdGluZw0KDQogICAgZGVmIF9fYWRkZW50cnkoc2VsZiwgbXNnLCBsaW5lbm89Tm9uZSwgaXNkb2NzdHJpbmc9MCk6DQogICAgICAgIGlmIGxpbmVubyBpcyBOb25lOg0KICAgICAgICAgICAgbGluZW5vID0gc2VsZi5fX2xpbmVubw0KICAgICAgICBpZiBub3QgbXNnIGluIHNlbGYuX19vcHRpb25zLnRvZXhjbHVkZToNCiAgICAgICAgICAgIGVudHJ5ID0gKHNlbGYuX19jdXJmaWxlLCBsaW5lbm8pDQogICAgICAgICAgICBzZWxmLl9fbWVzc2FnZXMuc2V0ZGVmYXVsdChtc2csIHt9KVtlbnRyeV0gPSBpc2RvY3N0cmluZw0KDQogICAgZGVmIHNldF9maWxlbmFtZShzZWxmLCBmaWxlbmFtZSk6DQogICAgICAgIHNlbGYuX19jdXJmaWxlID0gZmlsZW5hbWUNCiAgICAgICAgc2VsZi5fX2ZyZXNobW9kdWxlID0gMQ0KDQogICAgZGVmIHdyaXRlKHNlbGYsIGZwKToNCiAgICAgICAgb3B0aW9ucyA9IHNlbGYuX19vcHRpb25zDQogICAgICAgIHRpbWVzdGFtcCA9IHRpbWUuc3RyZnRpbWUoJyVZLSVtLSVkICVIOiVNKyVaJykNCiAgICAgICAgIyBUaGUgdGltZSBzdGFtcCBpbiB0aGUgaGVhZGVyIGRvZXNuJ3QgaGF2ZSB0aGUgc2FtZSBmb3JtYXQgYXMgdGhhdA0KICAgICAgICAjIGdlbmVyYXRlZCBieSB4Z2V0dGV4dC4uLg0KICAgICAgICBwcmludCA+PiBmcCwgcG90X2hlYWRlciAlIHsndGltZSc6IHRpbWVzdGFtcCwgJ3ZlcnNpb24nOiBfX3ZlcnNpb25fX30NCiAgICAgICAgIyBTb3J0IHRoZSBlbnRyaWVzLiAgRmlyc3Qgc29ydCBlYWNoIHBhcnRpY3VsYXIgZW50cnkncyBrZXlzLCB0aGVuDQogICAgICAgICMgc29ydCBhbGwgdGhlIGVudHJpZXMgYnkgdGhlaXIgZmlyc3QgaXRlbS4NCiAgICAgICAgcmV2ZXJzZSA9IHt9DQogICAgICAgIGZvciBrLCB2IGluIHNlbGYuX19tZXNzYWdlcy5pdGVtcygpOg0KICAgICAgICAgICAga2V5cyA9IHYua2V5cygpDQogICAgICAgICAgICBrZXlzLnNvcnQoKQ0KICAgICAgICAgICAgcmV2ZXJzZS5zZXRkZWZhdWx0KHR1cGxlKGtleXMpLCBbXSkuYXBwZW5kKChrLCB2KSkNCiAgICAgICAgcmtleXMgPSByZXZlcnNlLmtleXMoKQ0KICAgICAgICBya2V5cy5zb3J0KCkNCiAgICAgICAgZm9yIHJrZXkgaW4gcmtleXM6DQogICAgICAgICAgICByZW50cmllcyA9IHJldmVyc2VbcmtleV0NCiAgICAgICAgICAgIHJlbnRyaWVzLnNvcnQoKQ0KICAgICAgICAgICAgZm9yIGssIHYgaW4gcmVudHJpZXM6DQogICAgICAgICAgICAgICAgaXNkb2NzdHJpbmcgPSAwDQogICAgICAgICAgICAgICAgIyBJZiB0aGUgZW50cnkgd2FzIGdsZWFuZWQgb3V0IG9mIGEgZG9jc3RyaW5nLCB0aGVuIGFkZCBhDQogICAgICAgICAgICAgICAgIyBjb21tZW50IHN0YXRpbmcgc28uICBUaGlzIGlzIHRvIGFpZCB0cmFuc2xhdG9ycyB3aG8gbWF5IHdpc2gNCiAgICAgICAgICAgICAgICAjIHRvIHNraXAgdHJhbnNsYXRpbmcgc29tZSB1bmltcG9ydGFudCBkb2NzdHJpbmdzLg0KICAgICAgICAgICAgICAgIGlmIHJlZHVjZShvcGVyYXRvci5fX2FkZF9fLCB2LnZhbHVlcygpKToNCiAgICAgICAgICAgICAgICAgICAgaXNkb2NzdHJpbmcgPSAxDQogICAgICAgICAgICAgICAgIyBrIGlzIHRoZSBtZXNzYWdlIHN0cmluZywgdiBpcyBhIGRpY3Rpb25hcnktc2V0IG9mIChmaWxlbmFtZSwNCiAgICAgICAgICAgICAgICAjIGxpbmVubykgdHVwbGVzLiAgV2Ugd2FudCB0byBzb3J0IHRoZSBlbnRyaWVzIGluIHYgZmlyc3QgYnkNCiAgICAgICAgICAgICAgICAjIGZpbGUgbmFtZSBhbmQgdGhlbiBieSBsaW5lIG51bWJlci4NCiAgICAgICAgICAgICAgICB2ID0gdi5rZXlzKCkNCiAgICAgICAgICAgICAgICB2LnNvcnQoKQ0KICAgICAgICAgICAgICAgIGlmIG5vdCBvcHRpb25zLndyaXRlbG9jYXRpb25zOg0KICAgICAgICAgICAgICAgICAgICBwYXNzDQogICAgICAgICAgICAgICAgIyBsb2NhdGlvbiBjb21tZW50cyBhcmUgZGlmZmVyZW50IGIvdyBTb2xhcmlzIGFuZCBHTlU6DQogICAgICAgICAgICAgICAgZWxpZiBvcHRpb25zLmxvY2F0aW9uc3R5bGUgPT0gb3B0aW9ucy5TT0xBUklTOg0KICAgICAgICAgICAgICAgICAgICBmb3IgZmlsZW5hbWUsIGxpbmVubyBpbiB2Og0KICAgICAgICAgICAgICAgICAgICAgICAgZCA9IHsnZmlsZW5hbWUnOiBmaWxlbmFtZSwgJ2xpbmVubyc6IGxpbmVub30NCiAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ID4+ZnAsIF8oDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgJyMgRmlsZTogJShmaWxlbmFtZSlzLCBsaW5lOiAlKGxpbmVubylkJykgJSBkDQogICAgICAgICAgICAgICAgZWxpZiBvcHRpb25zLmxvY2F0aW9uc3R5bGUgPT0gb3B0aW9ucy5HTlU6DQogICAgICAgICAgICAgICAgICAgICMgZml0IGFzIG1hbnkgbG9jYXRpb25zIG9uIG9uZSBsaW5lLCBhcyBsb25nIGFzIHRoZQ0KICAgICAgICAgICAgICAgICAgICAjIHJlc3VsdGluZyBsaW5lIGxlbmd0aCBkb2Vzbid0IGV4Y2VlZHMgJ29wdGlvbnMud2lkdGgnDQogICAgICAgICAgICAgICAgICAgIGxvY2xpbmUgPSAnIzonDQogICAgICAgICAgICAgICAgICAgIGZvciBmaWxlbmFtZSwgbGluZW5vIGluIHY6DQogICAgICAgICAgICAgICAgICAgICAgICBkID0geydmaWxlbmFtZSc6IGZpbGVuYW1lLCAnbGluZW5vJzogbGluZW5vfQ0KICAgICAgICAgICAgICAgICAgICAgICAgcyA9IF8oJyAlKGZpbGVuYW1lKXM6JShsaW5lbm8pZCcpICUgZA0KICAgICAgICAgICAgICAgICAgICAgICAgaWYgbGVuKGxvY2xpbmUpICsgbGVuKHMpIDw9IG9wdGlvbnMud2lkdGg6DQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jbGluZSA9IGxvY2xpbmUgKyBzDQogICAgICAgICAgICAgICAgICAgICAgICBlbHNlOg0KICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaW50ID4+IGZwLCBsb2NsaW5lDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9jbGluZSA9ICIjOiIgKyBzDQogICAgICAgICAgICAgICAgICAgIGlmIGxlbihsb2NsaW5lKSA+IDI6DQogICAgICAgICAgICAgICAgICAgICAgICBwcmludCA+PiBmcCwgbG9jbGluZQ0KICAgICAgICAgICAgICAgIGlmIGlzZG9jc3RyaW5nOg0KICAgICAgICAgICAgICAgICAgICBwcmludCA+PiBmcCwgJyMsIGRvY3N0cmluZycNCiAgICAgICAgICAgICAgICBwcmludCA+PiBmcCwgJ21zZ2lkJywgbm9ybWFsaXplKGspDQogICAgICAgICAgICAgICAgcHJpbnQgPj4gZnAsICdtc2dzdHIgIiJcbicNCg0KDQoMDQpkZWYgbWFpbigpOg0KICAgIGdsb2JhbCBkZWZhdWx0X2tleXdvcmRzDQogICAgdHJ5Og0KICAgICAgICBvcHRzLCBhcmdzID0gZ2V0b3B0LmdldG9wdCgNCiAgICAgICAgICAgIHN5cy5hcmd2WzE6XSwNCiAgICAgICAgICAgICdhZDpERWhrOktubzpwOlM6VnZ3Ong6WDonLA0KICAgICAgICAgICAgWydleHRyYWN0LWFsbCcsICdkZWZhdWx0LWRvbWFpbj0nLCAnZXNjYXBlJywgJ2hlbHAnLA0KICAgICAgICAgICAgICdrZXl3b3JkPScsICduby1kZWZhdWx0LWtleXdvcmRzJywNCiAgICAgICAgICAgICAnYWRkLWxvY2F0aW9uJywgJ25vLWxvY2F0aW9uJywgJ291dHB1dD0nLCAnb3V0cHV0LWRpcj0nLA0KICAgICAgICAgICAgICdzdHlsZT0nLCAndmVyYm9zZScsICd2ZXJzaW9uJywgJ3dpZHRoPScsICdleGNsdWRlLWZpbGU9JywNCiAgICAgICAgICAgICAnZG9jc3RyaW5ncycsICduby1kb2NzdHJpbmdzJywNCiAgICAgICAgICAgICBdKQ0KICAgIGV4Y2VwdCBnZXRvcHQuZXJyb3IsIG1zZzoNCiAgICAgICAgdXNhZ2UoMSwgbXNnKQ0KDQogICAgIyBmb3IgaG9sZGluZyBvcHRpb24gdmFsdWVzDQogICAgY2xhc3MgT3B0aW9uczoNCiAgICAgICAgIyBjb25zdGFudHMNCiAgICAgICAgR05VID0gMQ0KICAgICAgICBTT0xBUklTID0gMg0KICAgICAgICAjIGRlZmF1bHRzDQogICAgICAgIGV4dHJhY3RhbGwgPSAwICMgRklYTUU6IGN1cnJlbnRseSB0aGlzIG9wdGlvbiBoYXMgbm8gZWZmZWN0IGF0IGFsbC4NCiAgICAgICAgZXNjYXBlID0gMA0KICAgICAgICBrZXl3b3JkcyA9IFtdDQogICAgICAgIG91dHBhdGggPSAnJw0KICAgICAgICBvdXRmaWxlID0gJ21lc3NhZ2VzLnBvdCcNCiAgICAgICAgd3JpdGVsb2NhdGlvbnMgPSAxDQogICAgICAgIGxvY2F0aW9uc3R5bGUgPSBHTlUNCiAgICAgICAgdmVyYm9zZSA9IDANCiAgICAgICAgd2lkdGggPSA3OA0KICAgICAgICBleGNsdWRlZmlsZW5hbWUgPSAnJw0KICAgICAgICBkb2NzdHJpbmdzID0gMA0KICAgICAgICBub2RvY3N0cmluZ3MgPSB7fQ0KDQogICAgb3B0aW9ucyA9IE9wdGlvbnMoKQ0KICAgIGxvY2F0aW9ucyA9IHsnZ251JyA6IG9wdGlvbnMuR05VLA0KICAgICAgICAgICAgICAgICAnc29sYXJpcycgOiBvcHRpb25zLlNPTEFSSVMsDQogICAgICAgICAgICAgICAgIH0NCg0KICAgICMgcGFyc2Ugb3B0aW9ucw0KICAgIGZvciBvcHQsIGFyZyBpbiBvcHRzOg0KICAgICAgICBpZiBvcHQgaW4gKCctaCcsICctLWhlbHAnKToNCiAgICAgICAgICAgIHVzYWdlKDApDQogICAgICAgIGVsaWYgb3B0IGluICgnLWEnLCAnLS1leHRyYWN0LWFsbCcpOg0KICAgICAgICAgICAgb3B0aW9ucy5leHRyYWN0YWxsID0gMQ0KICAgICAgICBlbGlmIG9wdCBpbiAoJy1kJywgJy0tZGVmYXVsdC1kb21haW4nKToNCiAgICAgICAgICAgIG9wdGlvbnMub3V0ZmlsZSA9IGFyZyArICcucG90Jw0KICAgICAgICBlbGlmIG9wdCBpbiAoJy1FJywgJy0tZXNjYXBlJyk6DQogICAgICAgICAgICBvcHRpb25zLmVzY2FwZSA9IDENCiAgICAgICAgZWxpZiBvcHQgaW4gKCctRCcsICctLWRvY3N0cmluZ3MnKToNCiAgICAgICAgICAgIG9wdGlvbnMuZG9jc3RyaW5ncyA9IDENCiAgICAgICAgZWxpZiBvcHQgaW4gKCctaycsICctLWtleXdvcmQnKToNCiAgICAgICAgICAgIG9wdGlvbnMua2V5d29yZHMuYXBwZW5kKGFyZykNCiAgICAgICAgZWxpZiBvcHQgaW4gKCctSycsICctLW5vLWRlZmF1bHQta2V5d29yZHMnKToNCiAgICAgICAgICAgIGRlZmF1bHRfa2V5d29yZHMgPSBbXQ0KICAgICAgICBlbGlmIG9wdCBpbiAoJy1uJywgJy0tYWRkLWxvY2F0aW9uJyk6DQogICAgICAgICAgICBvcHRpb25zLndyaXRlbG9jYXRpb25zID0gMQ0KICAgICAgICBlbGlmIG9wdCBpbiAoJy0tbm8tbG9jYXRpb24nLCk6DQogICAgICAgICAgICBvcHRpb25zLndyaXRlbG9jYXRpb25zID0gMA0KICAgICAgICBlbGlmIG9wdCBpbiAoJy1TJywgJy0tc3R5bGUnKToNCiAgICAgICAgICAgIG9wdGlvbnMubG9jYXRpb25zdHlsZSA9IGxvY2F0aW9ucy5nZXQoYXJnLmxvd2VyKCkpDQogICAgICAgICAgICBpZiBvcHRpb25zLmxvY2F0aW9uc3R5bGUgaXMgTm9uZToNCiAgICAgICAgICAgICAgICB1c2FnZSgxLCBfKCdJbnZhbGlkIHZhbHVlIGZvciAtLXN0eWxlOiAlcycpICUgYXJnKQ0KICAgICAgICBlbGlmIG9wdCBpbiAoJy1vJywgJy0tb3V0cHV0Jyk6DQogICAgICAgICAgICBvcHRpb25zLm91dGZpbGUgPSBhcmcNCiAgICAgICAgZWxpZiBvcHQgaW4gKCctcCcsICctLW91dHB1dC1kaXInKToNCiAgICAgICAgICAgIG9wdGlvbnMub3V0cGF0aCA9IGFyZw0KICAgICAgICBlbGlmIG9wdCBpbiAoJy12JywgJy0tdmVyYm9zZScpOg0KICAgICAgICAgICAgb3B0aW9ucy52ZXJib3NlID0gMQ0KICAgICAgICBlbGlmIG9wdCBpbiAoJy1WJywgJy0tdmVyc2lvbicpOg0KICAgICAgICAgICAgcHJpbnQgXygncHlnZXR0ZXh0LnB5ICh4Z2V0dGV4dCBmb3IgUHl0aG9uKSAlcycpICUgX192ZXJzaW9uX18NCiAgICAgICAgICAgIHN5cy5leGl0KDApDQogICAgICAgIGVsaWYgb3B0IGluICgnLXcnLCAnLS13aWR0aCcpOg0KICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgIG9wdGlvbnMud2lkdGggPSBpbnQoYXJnKQ0KICAgICAgICAgICAgZXhjZXB0IFZhbHVlRXJyb3I6DQogICAgICAgICAgICAgICAgdXNhZ2UoMSwgXygnLS13aWR0aCBhcmd1bWVudCBtdXN0IGJlIGFuIGludGVnZXI6ICVzJykgJSBhcmcpDQogICAgICAgIGVsaWYgb3B0IGluICgnLXgnLCAnLS1leGNsdWRlLWZpbGUnKToNCiAgICAgICAgICAgIG9wdGlvbnMuZXhjbHVkZWZpbGVuYW1lID0gYXJnDQogICAgICAgIGVsaWYgb3B0IGluICgnLVgnLCAnLS1uby1kb2NzdHJpbmdzJyk6DQogICAgICAgICAgICBmcCA9IG9wZW4oYXJnKQ0KICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgIHdoaWxlIDE6DQogICAgICAgICAgICAgICAgICAgIGxpbmUgPSBmcC5yZWFkbGluZSgpDQogICAgICAgICAgICAgICAgICAgIGlmIG5vdCBsaW5lOg0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWsNCiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5ub2RvY3N0cmluZ3NbbGluZVs6LTFdXSA9IDENCiAgICAgICAgICAgIGZpbmFsbHk6DQogICAgICAgICAgICAgICAgZnAuY2xvc2UoKQ0KDQogICAgIyBjYWxjdWxhdGUgZXNjYXBlcw0KICAgIG1ha2VfZXNjYXBlcyhvcHRpb25zLmVzY2FwZSkNCg0KICAgICMgY2FsY3VsYXRlIGFsbCBrZXl3b3Jkcw0KICAgIG9wdGlvbnMua2V5d29yZHMuZXh0ZW5kKGRlZmF1bHRfa2V5d29yZHMpDQoNCiAgICAjIGluaXRpYWxpemUgbGlzdCBvZiBzdHJpbmdzIHRvIGV4Y2x1ZGUNCiAgICBpZiBvcHRpb25zLmV4Y2x1ZGVmaWxlbmFtZToNCiAgICAgICAgdHJ5Og0KICAgICAgICAgICAgZnAgPSBvcGVuKG9wdGlvbnMuZXhjbHVkZWZpbGVuYW1lKQ0KICAgICAgICAgICAgb3B0aW9ucy50b2V4Y2x1ZGUgPSBmcC5yZWFkbGluZXMoKQ0KICAgICAgICAgICAgZnAuY2xvc2UoKQ0KICAgICAgICBleGNlcHQgSU9FcnJvcjoNCiAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsIF8oDQogICAgICAgICAgICAgICAgIkNhbid0IHJlYWQgLS1leGNsdWRlLWZpbGU6ICVzIikgJSBvcHRpb25zLmV4Y2x1ZGVmaWxlbmFtZQ0KICAgICAgICAgICAgc3lzLmV4aXQoMSkNCiAgICBlbHNlOg0KICAgICAgICBvcHRpb25zLnRvZXhjbHVkZSA9IFtdDQoNCiAgICAjIHJlc29sdmUgYXJncyB0byBtb2R1bGUgbGlzdHMNCiAgICBleHBhbmRlZCA9IFtdDQogICAgZm9yIGFyZyBpbiBhcmdzOg0KICAgICAgICBpZiBhcmcgPT0gJy0nOg0KICAgICAgICAgICAgZXhwYW5kZWQuYXBwZW5kKGFyZykNCiAgICAgICAgZWxzZToNCiAgICAgICAgICAgIGV4cGFuZGVkLmV4dGVuZChnZXRGaWxlc0Zvck5hbWUoYXJnKSkNCiAgICBhcmdzID0gZXhwYW5kZWQNCg0KICAgICMgc2x1cnAgdGhyb3VnaCBhbGwgdGhlIGZpbGVzDQogICAgZWF0ZXIgPSBUb2tlbkVhdGVyKG9wdGlvbnMpDQogICAgZm9yIGZpbGVuYW1lIGluIGFyZ3M6DQogICAgICAgIGlmIGZpbGVuYW1lID09ICctJzoNCiAgICAgICAgICAgIGlmIG9wdGlvbnMudmVyYm9zZToNCiAgICAgICAgICAgICAgICBwcmludCBfKCdSZWFkaW5nIHN0YW5kYXJkIGlucHV0JykNCiAgICAgICAgICAgIGZwID0gc3lzLnN0ZGluDQogICAgICAgICAgICBjbG9zZXAgPSAwDQogICAgICAgIGVsc2U6DQogICAgICAgICAgICBpZiBvcHRpb25zLnZlcmJvc2U6DQogICAgICAgICAgICAgICAgcHJpbnQgXygnV29ya2luZyBvbiAlcycpICUgZmlsZW5hbWUNCiAgICAgICAgICAgIGZwID0gb3BlbihmaWxlbmFtZSkNCiAgICAgICAgICAgIGNsb3NlcCA9IDENCiAgICAgICAgdHJ5Og0KICAgICAgICAgICAgZWF0ZXIuc2V0X2ZpbGVuYW1lKGZpbGVuYW1lKQ0KICAgICAgICAgICAgdHJ5Og0KICAgICAgICAgICAgICAgIHRva2VuaXplLnRva2VuaXplKGZwLnJlYWRsaW5lLCBlYXRlcikNCiAgICAgICAgICAgIGV4Y2VwdCB0b2tlbml6ZS5Ub2tlbkVycm9yLCBlOg0KICAgICAgICAgICAgICAgIHByaW50ID4+IHN5cy5zdGRlcnIsICclczogJXMsIGxpbmUgJWQsIGNvbHVtbiAlZCcgJSAoDQogICAgICAgICAgICAgICAgICAgIGVbMF0sIGZpbGVuYW1lLCBlWzFdWzBdLCBlWzFdWzFdKQ0KICAgICAgICBmaW5hbGx5Og0KICAgICAgICAgICAgaWYgY2xvc2VwOg0KICAgICAgICAgICAgICAgIGZwLmNsb3NlKCkNCg0KICAgICMgd3JpdGUgdGhlIG91dHB1dA0KICAgIGlmIG9wdGlvbnMub3V0ZmlsZSA9PSAnLSc6DQogICAgICAgIGZwID0gc3lzLnN0ZG91dA0KICAgICAgICBjbG9zZXAgPSAwDQogICAgZWxzZToNCiAgICAgICAgaWYgb3B0aW9ucy5vdXRwYXRoOg0KICAgICAgICAgICAgb3B0aW9ucy5vdXRmaWxlID0gb3MucGF0aC5qb2luKG9wdGlvbnMub3V0cGF0aCwgb3B0aW9ucy5vdXRmaWxlKQ0KICAgICAgICBmcCA9IG9wZW4ob3B0aW9ucy5vdXRmaWxlLCAndycpDQogICAgICAgIGNsb3NlcCA9IDENCiAgICB0cnk6DQogICAgICAgIGVhdGVyLndyaXRlKGZwKQ0KICAgIGZpbmFsbHk6DQogICAgICAgIGlmIGNsb3NlcDoNCiAgICAgICAgICAgIGZwLmNsb3NlKCkNCg0KDA0KaWYgX19uYW1lX18gPT0gJ19fbWFpbl9fJzoNCiAgICBtYWluKCkNCiAgICAjIHNvbWUgbW9yZSB0ZXN0IHN0cmluZ3MNCiAgICBfKHUnYSB1bmljb2RlIHN0cmluZycpDQogICAgIyB0aGlzIG9uZSBjcmVhdGVzIGEgd2FybmluZw0KICAgIF8oJyoqKiBTZWVuIHVuZXhwZWN0ZWQgdG9rZW4gIiUodG9rZW4pcyInKSAlIHsndG9rZW4nOiAndGVzdCd9DQogICAgXygnbW9yZScgJ3RoYW4nICdvbmUnICdzdHJpbmcnKQ0K