aW1wb3J0IHN5cwppbXBvcnQgYmRiCmltcG9ydCB0eXBlcwppbXBvcnQgb3MKCmltcG9ydCBXCmltcG9ydCBXQVNURWNvbnN0CmltcG9ydCBQeUJyb3dzZXIKaW1wb3J0IFFkCmltcG9ydCBFdnQKaW1wb3J0IExpc3RzCmltcG9ydCBNYWNPUwpfZmlsZW5hbWVzID0ge30KClNJTVBMRV9UWVBFUyA9ICgKCXR5cGVzLk5vbmVUeXBlLAoJdHlwZXMuSW50VHlwZSwKCXR5cGVzLkxvbmdUeXBlLAoJdHlwZXMuRmxvYXRUeXBlLAoJdHlwZXMuQ29tcGxleFR5cGUsCgl0eXBlcy5TdHJpbmdUeXBlCikKCgpjbGFzcyBEZWJ1Z2dlcihiZGIuQmRiKToKCQoJZGVmIF9faW5pdF9fKHNlbGYsIHRpdGxlID0gJ0RlYnVnZ2VyJyk6CgkJYmRiLkJkYi5fX2luaXRfXyhzZWxmKQoJCXNlbGYuY2xvc2VkID0gMQoJCXNlbGYudGl0bGUgPSB0aXRsZQoJCXNlbGYuYnJlYWtzdmlld2VyID0gTm9uZQoJCXNlbGYucmVzZXQoKQoJCXNlbGYudHJhY2luZyA9IDAKCQlzZWxmLnRyYWNpbmdtb25pdG9ydGltZSA9IEV2dC5UaWNrQ291bnQoKQoJCXNlbGYuZWRpdG9ycyA9IHt9CgkJCgkJcHJlZnMgPSBXLmdldGFwcGxpY2F0aW9uKCkuZ2V0cHJlZnMoKQoJCWlmIHByZWZzLmRlYnVnZ2VyOgoJCQlmb3IgZmlsZSwgYnJlYWtzIGluIHByZWZzLmRlYnVnZ2VyLmJyZWFrcy5pdGVtcygpOgoJCQkJZm9yIGIgaW4gYnJlYWtzOgoJCQkJCXNlbGYuc2V0X2JyZWFrKGZpbGUsIGIpCgkJCXNlbGYuYm91bmRzLCBzZWxmLmhvcnBhbmVzLCBzZWxmLnZlcnBhbmVzID0gcHJlZnMuZGVidWdnZXIud2luZG93c2V0dGluZ3MKCQkJc2VsZi50cmFjZW1hZ2ljID0gcHJlZnMuZGVidWdnZXIudHJhY2VtYWdpYwoJCWVsc2U6CgkJCXNlbGYuYnJlYWtzID0ge30KCQkJc2VsZi5ob3JwYW5lcyA9ICgwLjQsIDAuNikKCQkJc2VsZi52ZXJwYW5lcyA9ICgwLjMsIDAuMzUsIDAuMzUpCgkJCXNlbGYuYm91bmRzID0gKDYwMCwgNDAwKQoJCQlzZWxmLnRyYWNlbWFnaWMgPSAwCgkJc2VsZi5sYXN0c3RhY2tzZWwgPSBOb25lCgkKCWRlZiByZXNldChzZWxmKToKCQlzZWxmLmN1cnJlbnRmcmFtZSA9IE5vbmUKCQlzZWxmLmZpbGUgPSBOb25lCgkJc2VsZi5sYXN0c3RhY2sgPSBOb25lCgkJc2VsZi5yZWFzb24gPSAnTm90IHJ1bm5pbmcnCgkJc2VsZi5jb250aW51ZXdpdGhvdXRkZWJ1Z2dlciA9IDAKCQliZGIuQmRiLnJlc2V0KHNlbGYpCgkJc2VsZi5mb3JnZXQoKQoJCglkZWYgc3RhcnQoc2VsZiwgYm90dG9tZnJhbWUgPSBOb25lLCBydW5uaW5nID0gMCk6CgkJVy5nZXRhcHBsaWNhdGlvbigpLkRlYnVnZ2VyUXVpdCA9IGJkYi5CZGJRdWl0CgkJaW1wb3J0IE1lbnUKCQlNZW51LkhpbGl0ZU1lbnUoMCkKCQlpZiBzZWxmLmNsb3NlZDoKCQkJc2VsZi5zZXR1cHdpZGdldHMoc2VsZi50aXRsZSkKCQkJc2VsZi5jbG9zZWQgPSAwCgkJaWYgbm90IHNlbGYudy5wYXJlbnQuZGVidWdnZXJfcXVpdHRpbmc6CgkJCXNlbGYudy5zZWxlY3QoKQoJCQlyYWlzZSBXLkFsZXJ0RXJyb3IsICdUaGVyZSBpcyBhbm90aGVyIGRlYnVnZ2VyIHNlc3Npb24gYnVzeS4nCgkJc2VsZi5yZXNldCgpCgkJc2VsZi5ib3RmcmFtZSA9IGJvdHRvbWZyYW1lCgkJaWYgcnVubmluZzoKCQkJc2VsZi5zZXRfY29udGludWUoKQoJCQlzZWxmLnJlYXNvbiA9ICdSdW5uaW5niicKCQkJc2VsZi5zZXRzdGF0ZSgncnVubmluZycpCgkJZWxzZToKCQkJc2VsZi5zZXRfc3RlcCgpCgkJCXNlbGYucmVhc29uID0gJ3N0b3BwZWQnCgkJCXNlbGYuc2V0c3RhdGUoJ3N0b3BwZWQnKQoJCXN5cy5zZXR0cmFjZShzZWxmLnRyYWNlX2Rpc3BhdGNoKQoJCglkZWYgc3RvcChzZWxmKToKCQlzZWxmLnNldF9xdWl0KCkKCQlpZiBzZWxmLncucGFyZW50OgoJCQlzZWxmLmV4aXRfbWFpbmxvb3AoKQoJCQlzZWxmLnJlc2V0d2lkZ2V0cygpCgkKCWRlZiBzZXRfY29udGludWVfd2l0aG91dF9kZWJ1Z2dlcihzZWxmKToKCQlzeXMuc2V0dHJhY2UoTm9uZSkKCQlzZWxmLnNldF9xdWl0KCkKCQlzZWxmLmNsZWFyX3RyYWNlZnVuY3MoKQoJCXNlbGYuY29udGludWV3aXRob3V0ZGVidWdnZXIgPSAxCgkJaWYgaGFzYXR0cihzZWxmLCAidyIpIGFuZCBzZWxmLncucGFyZW50OgoJCQlzZWxmLmV4aXRfbWFpbmxvb3AoKQoJCQlzZWxmLnJlc2V0d2lkZ2V0cygpCgkKCWRlZiBjbGVhcl90cmFjZWZ1bmNzKHNlbGYpOgoJCXRyeToKCQkJcmFpc2UgJ3NwYW0nCgkJZXhjZXB0OgoJCQlwYXNzCgkJZnJhbWUgPSBzeXMuZXhjX3RyYWNlYmFjay50Yl9mcmFtZQoJCXdoaWxlIGZyYW1lIGlzIG5vdCBOb25lOgoJCQlkZWwgZnJhbWUuZl90cmFjZQoJCQlmcmFtZSA9IGZyYW1lLmZfYmFjawoJCglkZWYgcG9zdG1vcnRlbShzZWxmLCBleGNfdHlwZSwgZXhjX3ZhbHVlLCB0cmFjZWJhY2spOgoJCWlmIHNlbGYuY2xvc2VkOgoJCQlzZWxmLnNldHVwd2lkZ2V0cyhzZWxmLnRpdGxlKQoJCQlzZWxmLmNsb3NlZCA9IDAKCQlpZiBub3Qgc2VsZi53LnBhcmVudC5kZWJ1Z2dlcl9xdWl0dGluZzoKCQkJcmFpc2UgVy5BbGVydEVycm9yLCAnVGhlcmUgaXMgYW5vdGhlciBkZWJ1Z2dlciBzZXNzaW9uIGJ1c3kuJwoJCXNlbGYucmVzZXQoKQoJCWlmIHRyYWNlYmFjazoKCQkJc2VsZi5ib3RmcmFtZSA9IHRyYWNlYmFjay50Yl9mcmFtZQoJCQl3aGlsZSB0cmFjZWJhY2sudGJfbmV4dCA8PiBOb25lOgoJCQkJdHJhY2ViYWNrID0gdHJhY2ViYWNrLnRiX25leHQKCQkJZnJhbWUgPSB0cmFjZWJhY2sudGJfZnJhbWUKCQllbHNlOgoJCQlzZWxmLmJvdGZyYW1lID0gTm9uZQoJCQlmcmFtZSA9IE5vbmUKCQlzZWxmLncucGFuZXMuYm90dG9tLmJ1dHRvbnMua2lsbGJ1dHRvbi5lbmFibGUoMSkKCQlzZWxmLnJlYXNvbiA9ICcoZGVhZCkgJyArIHNlbGYuZm9ybWF0ZXhjZXB0aW9uKGV4Y190eXBlLCBleGNfdmFsdWUpCgkJc2VsZi53LnNlbGVjdCgpCgkJc2VsZi5zZXR1cChmcmFtZSwgdHJhY2ViYWNrKQoJCXNlbGYuc2V0c3RhdGUoJ2RlYWQnKQoJCXNlbGYuc2hvd3N0YWNrKHNlbGYuY3VyaW5kZXgpCgkJc2VsZi5zaG93ZnJhbWUoc2VsZi5jdXJpbmRleCkKCQoJZGVmIHNldHVwd2lkZ2V0cyhzZWxmLCB0aXRsZSk6CgkJc2VsZi53ID0gdyA9IFcuV2luZG93KHNlbGYuYm91bmRzLCB0aXRsZSwgbWluc2l6ZSA9ICg1MDAsIDMwMCkpCgkJCgkJdy5wYW5lcyA9IFcuSG9yaXpvbnRhbFBhbmVzKCg4LCA0LCAtOCwgLTgpLCBzZWxmLmhvcnBhbmVzKQoJCQoJCXcucGFuZXMuYnJvd3NlcnBhbmVzID0gYnJvd3NlcnBhbmVzID0gVy5WZXJ0aWNhbFBhbmVzKE5vbmUsIHNlbGYudmVycGFuZXMpCgkJCgkJYnJvd3NlcnBhbmVzLnN0YWNrbGlzdCA9IFcuR3JvdXAoTm9uZSkKCQlicm93c2VycGFuZXMuc3RhY2tsaXN0LnRpdGxlID0gVy5UZXh0Qm94KCg0LCAwLCAwLCAxMiksICdTdGFjaycpCgkJYnJvd3NlcnBhbmVzLnN0YWNrbGlzdC5zdGFjayA9IFcuTGlzdCgoMCwgMTYsIDAsIDApLCBjYWxsYmFjayA9IHNlbGYuZG9fc3RhY2ssIGZsYWdzID0gTGlzdHMubE9ubHlPbmUpCgkJCgkJYnJvd3NlcnBhbmVzLmxvY2FscyA9IFcuR3JvdXAoTm9uZSkKCQlicm93c2VycGFuZXMubG9jYWxzLnRpdGxlID0gVy5UZXh0Qm94KCg0LCAwLCAwLCAxMiksICdMb2NhbCB2YXJpYWJsZXMnKQoJCWJyb3dzZXJwYW5lcy5sb2NhbHMuYnJvd3NlciA9IFB5QnJvd3Nlci5Ccm93c2VyV2lkZ2V0KCgwLCAxNiwgMCwgMCkpCgkJCgkJYnJvd3NlcnBhbmVzLmdsb2JhbHMgPSBXLkdyb3VwKE5vbmUpCgkJYnJvd3NlcnBhbmVzLmdsb2JhbHMudGl0bGUgPSBXLlRleHRCb3goKDQsIDAsIDAsIDEyKSwgJ0dsb2JhbCB2YXJpYWJsZXMnKQoJCWJyb3dzZXJwYW5lcy5nbG9iYWxzLmJyb3dzZXIgPSBQeUJyb3dzZXIuQnJvd3NlcldpZGdldCgoMCwgMTYsIDAsIDApKQoJCQoJCXcucGFuZXMuYm90dG9tID0gYm90dG9tID0gVy5Hcm91cChOb25lKQoJCWJvdHRvbS5zcmMgPSBzcmMgPSBXLkdyb3VwKCgwLCA1MiwgMCwgMCkpCgkJc291cmNlID0gU291cmNlVmlld2VyKCgxLCAxLCAtMTUsIC0xNSksIHJlYWRvbmx5ID0gMSwgZGVidWdnZXIgPSBzZWxmKQoJCXNyYy5vcHRpb25zbWVudSA9IFcuUG9wdXBNZW51KCgtMTYsIDAsIDE2LCAxNiksIFtdKQoJCXNyYy5vcHRpb25zbWVudS5iaW5kKCc8Y2xpY2s+Jywgc2VsZi5tYWtlb3B0aW9uc21lbnUpCgkJCgkJc3JjLl9iYXJ4ID0gVy5TY3JvbGxiYXIoKDAsIC0xNiwgLTE1LCAxNiksIHNvdXJjZS5oc2Nyb2xsLCBtYXggPSAzMjc2NykKCQlzcmMuX2JhcnkgPSBXLlNjcm9sbGJhcigoLTE2LCAxNSwgMTYsIC0xNSksIHNvdXJjZS52c2Nyb2xsLCBtYXggPSAzMjc2NykKCQlzcmMuc291cmNlID0gc291cmNlCgkJc3JjLmZyYW1lID0gVy5GcmFtZSgoMCwgMCwgLTE1LCAtMTUpKQoJCQoJCWJvdHRvbS50cmFjaW5nbW9uaXRvciA9IFRyYWNpbmdNb25pdG9yKCgwLCAyMywgNiwgNikpCgkJYm90dG9tLnN0YXRlID0gVy5UZXh0Qm94KCgxMiwgMjAsIDAsIDE2KSwgc2VsZi5yZWFzb24pCgkJCgkJYm90dG9tLnNyY3RpdGxlID0gVy5UZXh0Qm94KCgxMiwgMzYsIDAsIDE0KSkKCQlib3R0b20uYnV0dG9ucyA9IGJ1dHRvbnMgPSBXLkdyb3VwKCgxMiwgMCwgMCwgMTYpKQoJCQoJCWJ1dHRvbnMucnVuYnV0dG9uID0gVy5CdXR0b24oKDAsIDAsIDUwLCAxNiksICJSdW4iLCBzZWxmLmRvX3J1bikKCQlidXR0b25zLnN0b3BidXR0b24gPSBXLkJ1dHRvbigoNTgsIDAsIDUwLCAxNiksICJTdG9wIiwgc2VsZi5kb19zdG9wKQoJCWJ1dHRvbnMua2lsbGJ1dHRvbiA9IFcuQnV0dG9uKCgxMTYsIDAsIDUwLCAxNiksICJLaWxsIiwgc2VsZi5kb19raWxsKQoJCWJ1dHRvbnMubGluZSA9IFcuVmVydGljYWxMaW5lKCgxNzMsIDAsIDAsIDApKQoJCWJ1dHRvbnMuc3RlcGJ1dHRvbiA9IFcuQnV0dG9uKCgxODEsIDAsIDUwLCAxNiksICJTdGVwIiwgc2VsZi5kb19zdGVwKQoJCWJ1dHRvbnMuc3RlcGluYnV0dG9uID0gVy5CdXR0b24oKDIzOSwgMCwgNTAsIDE2KSwgIlN0ZXAgaW4iLCBzZWxmLmRvX3N0ZXBpbikKCQlidXR0b25zLnN0ZXBvdXRidXR0b24gPSBXLkJ1dHRvbigoMjk3LCAwLCA1MCwgMTYpLCAiU3RlcCBvdXQiLCBzZWxmLmRvX3N0ZXBvdXQpCgkJCgkJdy5iaW5kKCdjbWRyJywgYnV0dG9ucy5ydW5idXR0b24ucHVzaCkKCQl3LmJpbmQoJ2NtZC4nLCBidXR0b25zLnN0b3BidXR0b24ucHVzaCkKCQl3LmJpbmQoJ2NtZGsnLCBidXR0b25zLmtpbGxidXR0b24ucHVzaCkKCQl3LmJpbmQoJ2NtZHMnLCBidXR0b25zLnN0ZXBidXR0b24ucHVzaCkKCQl3LmJpbmQoJ2NtZHQnLCBidXR0b25zLnN0ZXBpbmJ1dHRvbi5wdXNoKQoJCXcuYmluZCgnY21kdScsIGJ1dHRvbnMuc3RlcG91dGJ1dHRvbi5wdXNoKQoJCQoJCXcuYmluZCgnPGNsb3NlPicsIHNlbGYuY2xvc2UpCgkJCgkJdy5vcGVuKCkKCQl3Lnh4eF9fX3NlbGVjdCh3LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlKQoJCglkZWYgbWFrZW9wdGlvbnNtZW51KHNlbGYpOgoJCW9wdGlvbnMgPSBbKCdDbGVhciBicmVha3BvaW50cycsIHNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZS5jbGVhcmJyZWFrcG9pbnRzKSwgCgkJCQkoJ0NsZWFyIGFsbCBicmVha3BvaW50cycsIHNlbGYuY2xlYXJfYWxsX2JyZWFrcyksCgkJCQkoJ0VkaXQgYnJlYWtwb2ludHOKJywgc2VsZi5lZGl0X2JyZWFrcyksICctJywKCQkJCShzZWxmLnRyYWNlbWFnaWMgYW5kIAoJCQkJCSdEaXNhYmxlIF9fbWFnaWNfXyB0cmFjaW5nJyBvciAnRW5hYmxlIF9fbWFnaWNfXyB0cmFjaW5nJywgc2VsZi50b2dnbGVtYWdpYyldCgkJc2VsZi53LnBhbmVzLmJvdHRvbS5zcmMub3B0aW9uc21lbnUuc2V0KG9wdGlvbnMpCgkKCWRlZiBlZGl0X2JyZWFrcyhzZWxmKToKCQlpZiBzZWxmLmJyZWFrc3ZpZXdlcjoKCQkJc2VsZi5icmVha3N2aWV3ZXIuc2VsZWN0KCkKCQllbHNlOgoJCQlzZWxmLmJyZWFrc3ZpZXdlciA9IEJyZWFrcG9pbnRzVmlld2VyKHNlbGYpCgkKCWRlZiB0b2dnbGVtYWdpYyhzZWxmKToKCQlzZWxmLnRyYWNlbWFnaWMgPSBub3Qgc2VsZi50cmFjZW1hZ2ljCgkKCWRlZiBzZXRzdGF0ZShzZWxmLCBzdGF0ZSk6CgkJc2VsZi53LnBhbmVzLmJvdHRvbS50cmFjaW5nbW9uaXRvci5yZXNldCgpCgkJc2VsZi53LnBhbmVzLmJvdHRvbS5zdGF0ZS5zZXQoc2VsZi5yZWFzb24pCgkJYnV0dG9ucyA9IHNlbGYudy5wYW5lcy5ib3R0b20uYnV0dG9ucwoJCWlmIHN0YXRlID09ICdzdG9wcGVkJzoKCQkJYnV0dG9ucy5ydW5idXR0b24uZW5hYmxlKDEpCgkJCWJ1dHRvbnMuc3RvcGJ1dHRvbi5lbmFibGUoMCkKCQkJYnV0dG9ucy5raWxsYnV0dG9uLmVuYWJsZSgxKQoJCQlidXR0b25zLnN0ZXBidXR0b24uZW5hYmxlKDEpCgkJCWJ1dHRvbnMuc3RlcGluYnV0dG9uLmVuYWJsZSgxKQoJCQlidXR0b25zLnN0ZXBvdXRidXR0b24uZW5hYmxlKDEpCgkJZWxpZiBzdGF0ZSA9PSAncnVubmluZyc6CgkJCWJ1dHRvbnMucnVuYnV0dG9uLmVuYWJsZSgwKQoJCQlidXR0b25zLnN0b3BidXR0b24uZW5hYmxlKDEpCgkJCWJ1dHRvbnMua2lsbGJ1dHRvbi5lbmFibGUoMSkKCQkJYnV0dG9ucy5zdGVwYnV0dG9uLmVuYWJsZSgwKQoJCQlidXR0b25zLnN0ZXBpbmJ1dHRvbi5lbmFibGUoMCkKCQkJYnV0dG9ucy5zdGVwb3V0YnV0dG9uLmVuYWJsZSgwKQoJCWVsaWYgc3RhdGUgPT0gJ2lkbGUnOgoJCQlidXR0b25zLnJ1bmJ1dHRvbi5lbmFibGUoMCkKCQkJYnV0dG9ucy5zdG9wYnV0dG9uLmVuYWJsZSgwKQoJCQlidXR0b25zLmtpbGxidXR0b24uZW5hYmxlKDApCgkJCWJ1dHRvbnMuc3RlcGJ1dHRvbi5lbmFibGUoMCkKCQkJYnV0dG9ucy5zdGVwaW5idXR0b24uZW5hYmxlKDApCgkJCWJ1dHRvbnMuc3RlcG91dGJ1dHRvbi5lbmFibGUoMCkKCQllbGlmIHN0YXRlID09ICdkZWFkJzoKCQkJYnV0dG9ucy5ydW5idXR0b24uZW5hYmxlKDApCgkJCWJ1dHRvbnMuc3RvcGJ1dHRvbi5lbmFibGUoMCkKCQkJYnV0dG9ucy5raWxsYnV0dG9uLmVuYWJsZSgxKQoJCQlidXR0b25zLnN0ZXBidXR0b24uZW5hYmxlKDApCgkJCWJ1dHRvbnMuc3RlcGluYnV0dG9uLmVuYWJsZSgwKQoJCQlidXR0b25zLnN0ZXBvdXRidXR0b24uZW5hYmxlKDApCgkJZWxzZToKCQkJcHJpbnQgJ3Vua25vd24gc3RhdGU6Jywgc3RhdGUKCQoJZGVmIHJlc2V0d2lkZ2V0cyhzZWxmKToKCQlzZWxmLnJlYXNvbiA9ICcnCgkJc2VsZi53LnBhbmVzLmJvdHRvbS5zcmN0aXRsZS5zZXQoJycpCgkJc2VsZi53LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlLnNldCgnJykKCQlzZWxmLncucGFuZXMuYnJvd3NlcnBhbmVzLnN0YWNrbGlzdC5zdGFjay5zZXQoW10pCgkJc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5sb2NhbHMuYnJvd3Nlci5zZXQoe30pCgkJc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5nbG9iYWxzLmJyb3dzZXIuc2V0KHt9KQoJCXNlbGYuc2V0c3RhdGUoJ2lkbGUnKQoJCgkjIFcgY2FsbGJhY2tzCgkKCWRlZiBjbG9zZShzZWxmKToKCQlzZWxmLnNldF9xdWl0KCkKCQlzZWxmLmV4aXRfbWFpbmxvb3AoKQoJCXNlbGYuY2xvc2VkID0gMQoJCQoJCXNlbGYudW5yZWdpc3Rlcl9lZGl0b3Ioc2VsZi53LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlLCAKCQkJCXNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZS5maWxlKQoJCXNlbGYuaG9ycGFuZXMgPSBzZWxmLncucGFuZXMuZ2V0cGFuZXNpemVzKCkKCQlzZWxmLnZlcnBhbmVzID0gc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5nZXRwYW5lc2l6ZXMoKQoJCXNlbGYuYm91bmRzID0gc2VsZi53LmdldGJvdW5kcygpCgkJcHJlZnMgPSBXLmdldGFwcGxpY2F0aW9uKCkuZ2V0cHJlZnMoKQoJCXByZWZzLmRlYnVnZ2VyLmJyZWFrcyA9IHNlbGYuYnJlYWtzCgkJcHJlZnMuZGVidWdnZXIud2luZG93c2V0dGluZ3MgPSBzZWxmLmJvdW5kcywgc2VsZi5ob3JwYW5lcywgc2VsZi52ZXJwYW5lcwoJCXByZWZzLmRlYnVnZ2VyLnRyYWNlbWFnaWMgPSBzZWxmLnRyYWNlbWFnaWMKCQlwcmVmcy5zYXZlKCkKCQoJIyBzdGFjayBsaXN0IGNhbGxiYWNrCgkKCWRlZiBkb19zdGFjayhzZWxmLCBpc2RibCk6CgkJc2VsID0gc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5zdGFja2xpc3Quc3RhY2suZ2V0c2VsZWN0aW9uKCkKCQlpZiBpc2RibDoKCQkJaWYgc2VsOgoJCQkJZnJhbWUsIGxpbmVubyA9IHNlbGYuc3RhY2tbc2VsWzBdICsgMV0KCQkJCWZpbGVuYW1lID0gZnJhbWUuZl9jb2RlLmNvX2ZpbGVuYW1lCgkJCQllZGl0b3IgPSBzZWxmLncuX3BhcmVudHdpbmRvdy5wYXJlbnQub3BlbnNjcmlwdChmaWxlbmFtZSwgbGluZW5vKQoJCQkJaWYgc2VsZi5icmVha3MuaGFzX2tleShmaWxlbmFtZSk6CgkJCQkJZWRpdG9yLnNob3dicmVha3BvaW50cygxKQoJCWVsc2U6CgkJCWlmIHNlbCBhbmQgc2VsIDw+IHNlbGYubGFzdHN0YWNrc2VsOgoJCQkJc2VsZi5zaG93ZnJhbWUoc2VsWzBdICsgMSkKCQkJc2VsZi5sYXN0c3RhY2tzZWwgPSBzZWwKCQoJZGVmIGdldGVkaXRvcihzZWxmLCBmaWxlbmFtZSk6CgkJaWYgZmlsZW5hbWVbOjFdID09ICc8JyBhbmQgZmlsZW5hbWVbLTE6XSA9PSAnPic6CgkJCWVkaXRvciA9IFcuZ2V0YXBwbGljYXRpb24oKS5nZXRzY3JpcHQoZmlsZW5hbWVbMTotMV0pCgkJZWxzZToKCQkJZWRpdG9yID0gVy5nZXRhcHBsaWNhdGlvbigpLmdldHNjcmlwdChmaWxlbmFtZSkKCQlyZXR1cm4gZWRpdG9yCgkKCSMgYnV0dG9uIGNhbGxiYWNrcwoJCglkZWYgZG9fcnVuKHNlbGYpOgoJCXNlbGYucnVubmluZygpCgkJc2VsZi5zZXRfY29udGludWUoKQoJCXNlbGYuZXhpdF9tYWlubG9vcCgpCgkKCWRlZiBkb19zdG9wKHNlbGYpOgoJCXNlbGYuc2V0X3N0ZXAoKQoJCglkZWYgZG9fa2lsbChzZWxmKToKCQlzZWxmLnNldF9xdWl0KCkKCQlzZWxmLmV4aXRfbWFpbmxvb3AoKQoJCXNlbGYucmVzZXR3aWRnZXRzKCkKCQoJZGVmIGRvX3N0ZXAoc2VsZik6CgkJc2VsZi5ydW5uaW5nKCkKCQlzZWxmLnNldF9uZXh0KHNlbGYuY3VyZnJhbWUpCgkJc2VsZi5leGl0X21haW5sb29wKCkKCQoJZGVmIGRvX3N0ZXBpbihzZWxmKToKCQlzZWxmLnJ1bm5pbmcoKQoJCXNlbGYuc2V0X3N0ZXAoKQoJCXNlbGYuZXhpdF9tYWlubG9vcCgpCgkKCWRlZiBkb19zdGVwb3V0KHNlbGYpOgoJCXNlbGYucnVubmluZygpCgkJc2VsZi5zZXRfcmV0dXJuKHNlbGYuY3VyZnJhbWUpCgkJc2VsZi5leGl0X21haW5sb29wKCkKCQoJZGVmIHJ1bm5pbmcoc2VsZik6CgkJVy5TZXRDdXJzb3IoJ3dhdGNoJykKCQlzZWxmLnJlYXNvbiA9ICdSdW5uaW5niicKCQlzZWxmLnNldHN0YXRlKCdydW5uaW5nJykKCQkjc2VsZi53LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlLnNldCgnJykKCQkjc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5zdGFja2xpc3Quc3RhY2suc2V0KFtdKQoJCSNzZWxmLncucGFuZXMuYnJvd3NlcnBhbmVzLmxvY2Fscy5icm93c2VyLnNldCh7fSkKCQkjc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5nbG9iYWxzLmJyb3dzZXIuc2V0KHt9KQoJCglkZWYgZXhpdF9tYWlubG9vcChzZWxmKToKCQlzZWxmLncucGFyZW50LmRlYnVnZ2VyX3F1aXR0aW5nID0gMQoJCgkjCgkKCWRlZiBzaG93ZnJhbWUoc2VsZiwgc3RhY2tpbmRleCk6CgkJKGZyYW1lLCBsaW5lbm8pID0gc2VsZi5zdGFja1tzdGFja2luZGV4XQoJCVcuU2V0Q3Vyc29yKCd3YXRjaCcpCgkJZmlsZW5hbWUgPSBmcmFtZS5mX2NvZGUuY29fZmlsZW5hbWUKCQlpZiBmaWxlbmFtZSA8PiBzZWxmLmZpbGU6CgkJCWVkaXRvciA9IHNlbGYuZ2V0ZWRpdG9yKGZpbGVuYW1lKQoJCQlpZiBlZGl0b3I6CgkJCQlzZWxmLncucGFuZXMuYm90dG9tLnNyYy5zb3VyY2Uuc2V0KGVkaXRvci5nZXQoKSwgZmlsZW5hbWUpCgkJCWVsc2U6CgkJCQl0cnk6CgkJCQkJZiA9IG9wZW4oZmlsZW5hbWUsICdyYicpCgkJCQkJZGF0YSA9IGYucmVhZCgpCgkJCQkJZi5jbG9zZSgpCgkJCQlleGNlcHQgSU9FcnJvcjoKCQkJCQlpZiBmaWxlbmFtZVstMzpdID09ICcucHknOgoJCQkJCQlpbXBvcnQgaW1wCgkJCQkJCW1vZG5hbWUgPSBvcy5wYXRoLmJhc2VuYW1lKGZpbGVuYW1lKVs6LTNdCgkJCQkJCXRyeToKCQkJCQkJCWYsIGZpbGVuYW1lLCAoc3VmZiwgbW9kZSwgZHVtbXkpID0gaW1wLmZpbmRfbW9kdWxlKG1vZG5hbWUpCgkJCQkJCWV4Y2VwdCBJbXBvcnRFcnJvcjoKCQkJCQkJCXNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZS5zZXQoJ2Nhbrl0IGZpbmQgZmlsZScpCgkJCQkJCWVsc2U6CgkJCQkJCQlpZiBmOgoJCQkJCQkJCWYuY2xvc2UoKQoJCQkJCQkJaWYgZiBhbmQgc3VmZiA9PSAnLnB5JzoKCQkJCQkJCQlmID0gb3BlbihmaWxlbmFtZSwgJ3JiJykKCQkJCQkJCQlkYXRhID0gZi5yZWFkKCkKCQkJCQkJCQlmLmNsb3NlKCkKCQkJCQkJCQlzZWxmLncucGFuZXMuYm90dG9tLnNyYy5zb3VyY2Uuc2V0KGRhdGEsIGZpbGVuYW1lKQoJCQkJCQkJZWxzZToKCQkJCQkJCQlzZWxmLncucGFuZXMuYm90dG9tLnNyYy5zb3VyY2Uuc2V0KCdjYW65dCBmaW5kIGZpbGUnKQoJCQkJCWVsc2U6CgkJCQkJCXNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZS5zZXQoJ2Nhbrl0IGZpbmQgZmlsZScpCgkJCQllbHNlOgoJCQkJCXNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZS5zZXQoZGF0YSwgZmlsZW5hbWUpCgkJCXNlbGYuZmlsZSA9IGZpbGVuYW1lCgkJc2VsZi53LnBhbmVzLmJvdHRvbS5zcmN0aXRsZS5zZXQoJ1NvdXJjZTogJyArIGZpbGVuYW1lICsgKChsaW5lbm8gPiAwKSBhbmQgKCcgKGxpbmUgJWQpJyAlIGxpbmVubykgb3IgJyAnKSkKCQlzZWxmLmdvdG9fbGluZShsaW5lbm8pCgkJc2VsZi5saW5lbm8gPSBsaW5lbm8KCQlzZWxmLnNob3d2YXJzKChmcmFtZSwgbGluZW5vKSkKCQoJZGVmIHNob3d2YXJzKHNlbGYsIChmcmFtZSwgbGluZW5vKSk6CgkJaWYgZnJhbWUuZl9sb2NhbHMgaXMgbm90IGZyYW1lLmZfZ2xvYmFsczoKCQkJbG9jYWxzID0gZnJhbWUuZl9sb2NhbHMKCQllbHNlOgoJCQlsb2NhbHMgPSB7J1NhbWUgYXMgR2xvYmFscyc6Jyd9CgkJZmlsdGVyZWRsb2NhbHMgPSB7fQoJCWZvciBrZXksIHZhbHVlIGluIGxvY2Fscy5pdGVtcygpOgoJCQkjIGVtcHR5IGtleSBpcyBtYWdpYyBmb3IgUHl0aG9uIDEuNDsgJy4nIGlzIG1hZ2ljIGZvciAxLjUuLi4KCQkJaWYgbm90IGtleSBvciBrZXlbMF0gPD4gJy4nOgoJCQkJZmlsdGVyZWRsb2NhbHNba2V5XSA9IHZhbHVlCgkJc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5sb2NhbHMuYnJvd3Nlci5zZXQoZmlsdGVyZWRsb2NhbHMpCgkJc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5nbG9iYWxzLmJyb3dzZXIuc2V0KGZyYW1lLmZfZ2xvYmFscykKCQoJZGVmIHNob3dzdGFjayhzZWxmLCBzdGFja2luZGV4KToKCQlzdGFjayA9IFtdCgkJZm9yIGZyYW1lLCBsaW5lbm8gaW4gc2VsZi5zdGFja1sxOl06CgkJCWZpbGVuYW1lID0gZnJhbWUuZl9jb2RlLmNvX2ZpbGVuYW1lCgkJCXRyeToKCQkJCWZpbGVuYW1lID0gX2ZpbGVuYW1lc1tmaWxlbmFtZV0KCQkJZXhjZXB0IEtleUVycm9yOgoJCQkJaWYgZmlsZW5hbWVbOjFdICsgZmlsZW5hbWVbLTE6XSA8PiAnPD4nOgoJCQkJCWZpbGVuYW1lID0gb3MucGF0aC5iYXNlbmFtZShmaWxlbmFtZSkKCQkJCV9maWxlbmFtZXNbZnJhbWUuZl9jb2RlLmNvX2ZpbGVuYW1lXSA9IGZpbGVuYW1lCgkJCWZ1bmNuYW1lID0gZnJhbWUuZl9jb2RlLmNvX25hbWUKCQkJaWYgZnVuY25hbWUgPT0gJz8nOgoJCQkJZnVuY25hbWUgPSAnPHRvcGxldmVsPicKCQkJc3RhY2suYXBwZW5kKGZpbGVuYW1lICsgJzogJyArIGZ1bmNuYW1lKQoJCWlmIHN0YWNrIDw+IHNlbGYubGFzdHN0YWNrOgoJCQlzZWxmLncucGFuZXMuYnJvd3NlcnBhbmVzLnN0YWNrbGlzdC5zdGFjay5zZXQoc3RhY2spCgkJCXNlbGYubGFzdHN0YWNrID0gc3RhY2sKCQlzZWwgPSBbc3RhY2tpbmRleCAtIDFdCgkJc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5zdGFja2xpc3Quc3RhY2suc2V0c2VsZWN0aW9uKHNlbCkKCQlzZWxmLmxhc3RzdGFja3NlbCA9IHNlbAoJCglkZWYgZ290b19saW5lKHNlbGYsIGxpbmVubyk6CgkJaWYgbGluZW5vID4gMDoKCQkJc2VsZi53LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlLnNlbGVjdGxpbmUobGluZW5vIC0gMSkKCQllbHNlOgoJCQlzZWxmLncucGFuZXMuYm90dG9tLnNyYy5zb3VyY2Uuc2V0c2VsZWN0aW9uKDAsIDApCgkKCSMgYmRiIGVudHJ5IHBvaW50cwoJCiMJZGVmIHVzZXJfY2FsbChzZWxmLCBmcmFtZSwgYXJndW1lbnRfbGlzdCk6CiMJCXNlbGYucmVhc29uID0gJ0NhbGxpbmcnCiMJCXNlbGYuaW50ZXJhY3Rpb24oZnJhbWUsIE5vbmUpCgkKCWRlZiB1c2VyX2xpbmUoc2VsZiwgZnJhbWUpOgoJCSMgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgd2hlbiB3ZSBzdG9wIG9yIGJyZWFrIGF0IHRoaXMgbGluZQoJCXNlbGYucmVhc29uID0gJ1N0b3BwZWQnCgkJc2VsZi5pbnRlcmFjdGlvbihmcmFtZSwgTm9uZSkKCQoJZGVmIHVzZXJfcmV0dXJuKHNlbGYsIGZyYW1lLCByZXR1cm5fdmFsdWUpOgoJCSMgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgd2hlbiBhIHJldHVybiB0cmFwIGlzIHNldCBoZXJlCgkJZm5hbWUgPSBmcmFtZS5mX2NvZGUuY29fbmFtZQoJCWlmIGZuYW1lIDw+ICc/JzoKCQkJc2VsZi5yZWFzb24gPSAnUmV0dXJuaW5nIGZyb20gJXMoKScgJSBmcmFtZS5mX2NvZGUuY29fbmFtZQoJCQlmcmFtZS5mX2xvY2Fsc1snX19yZXR1cm5fXyddID0gcmV0dXJuX3ZhbHVlCgkJZWxpZiBmcmFtZS5mX2JhY2sgaXMgc2VsZi5ib3RmcmFtZToKCQkJc2VsZi5yZWFzb24gPSAnRG9uZScKCQllbHNlOgoJCQlzZWxmLnJlYXNvbiA9ICdSZXR1cm5pbmcnCgkJc2VsZi5pbnRlcmFjdGlvbihmcmFtZSwgTm9uZSwgMSkKCQoJZGVmIHVzZXJfZXhjZXB0aW9uKHNlbGYsIGZyYW1lLCAoZXhjX3R5cGUsIGV4Y192YWx1ZSwgZXhjX3RyYWNlYmFjaykpOgoJCSMgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgd2hlbiB3ZSBzdG9wIG9yIGJyZWFrIGF0IHRoaXMgbGluZQoJCXNlbGYucmVhc29uID0gc2VsZi5mb3JtYXRleGNlcHRpb24oZXhjX3R5cGUsIGV4Y192YWx1ZSkKCQlzZWxmLmludGVyYWN0aW9uKGZyYW1lLCBleGNfdHJhY2ViYWNrKQoJCglkZWYgZm9ybWF0ZXhjZXB0aW9uKHNlbGYsIGV4Y190eXBlLCBleGNfdmFsdWUpOgoJCWlmIGV4Y190eXBlID09IFN5bnRheEVycm9yOgoJCQl0cnk6CgkJCQl2YWx1ZSwgKGZpbGVuYW1lLCBsaW5lbm8sIGNoYXJubywgbGluZSkgPSBleGNfdmFsdWUKCQkJZXhjZXB0OgoJCQkJcGFzcwoJCQllbHNlOgoJCQkJcmV0dXJuIHN0cihleGNfdHlwZSkgKyAnOiAnICsgc3RyKHZhbHVlKQoJCWlmIHR5cGUoZXhjX3R5cGUpID09IHR5cGVzLkNsYXNzVHlwZToKCQkJbmljZSA9IGV4Y190eXBlLl9fbmFtZV9fCgkJZWxzZToKCQkJbmljZSA9IHN0cihleGNfdHlwZSkKCQl2YWx1ZSA9IHN0cihleGNfdmFsdWUpCgkJaWYgZXhjX3ZhbHVlIGFuZCB2YWx1ZToKCQkJbmljZSA9IG5pY2UgKyAiOiAiICsgdmFsdWUKCQlyZXR1cm4gbmljZQoJCglkZWYgZm9yZ2V0KHNlbGYpOgoJCXNlbGYuc3RhY2sgPSBbXQoJCXNlbGYuY3VyaW5kZXggPSAwCgkJc2VsZi5jdXJmcmFtZSA9IE5vbmUKCQoJZGVmIHNldHVwKHNlbGYsIGYsIHQsIGlzcmV0dXJuaW5nID0gMCk6CgkJc2VsZi5mb3JnZXQoKQoJCXNlbGYuc3RhY2ssIHNlbGYuY3VyaW5kZXggPSBzZWxmLmdldF9zdGFjayhmLCB0KQoJCXNlbGYuY3VyZnJhbWUgPSBzZWxmLnN0YWNrW3NlbGYuY3VyaW5kZXggLSBpc3JldHVybmluZ11bMF0KCQoJZGVmIGludGVyYWN0aW9uKHNlbGYsIGZyYW1lLCB0cmFjZWJhY2ssIGlzcmV0dXJuaW5nID0gMCk6CgkJc2F2ZXBvcnQgPSBRZC5HZXRQb3J0KCkKCQlzZWxmLncuc2VsZWN0KCkKCQl0cnk6CgkJCXNlbGYuc2V0dXAoZnJhbWUsIHRyYWNlYmFjaywgaXNyZXR1cm5pbmcpCgkJCXNlbGYuc2V0c3RhdGUoJ3N0b3BwZWQnKQoJCQlzdGFja2luZGV4ID0gc2VsZi5jdXJpbmRleAoJCQlpZiBpc3JldHVybmluZzoKCQkJCWlmIGZyYW1lLmZfYmFjayBpcyBub3Qgc2VsZi5ib3RmcmFtZToKCQkJCQlzdGFja2luZGV4ID0gc3RhY2tpbmRleCAtIDEKCQkJc2VsZi5zaG93c3RhY2soc3RhY2tpbmRleCkKCQkJc2VsZi5zaG93ZnJhbWUoc3RhY2tpbmRleCkKCQkJc2VsZi53LnBhcmVudC5kZWJ1Z2dlcl9tYWlubG9vcCgpCgkJCXNlbGYuZm9yZ2V0KCkKCQlmaW5hbGx5OgoJCQlRZC5TZXRQb3J0KHNhdmVwb3J0KQoJCgkjIGJkYiBjdXN0b21pemF0aW9uCgkKCWRlZiB0cmFjZV9kaXNwYXRjaChzZWxmLCBmcmFtZSwgZXZlbnQsIGFyZywgVGlja0NvdW50ID0gRXZ0LlRpY2tDb3VudCk6CgkJaWYgVGlja0NvdW50KCkgLSBzZWxmLnRyYWNpbmdtb25pdG9ydGltZSA+IDE1OgoJCQlzZWxmLnRyYWNpbmdtb25pdG9ydGltZSA9IFRpY2tDb3VudCgpCgkJCXNlbGYudy5wYW5lcy5ib3R0b20udHJhY2luZ21vbml0b3IudG9nZ2xlKCkKCQl0cnk6CgkJCXRyeToKCQkJCU1hY09TLkVuYWJsZUFwcHN3aXRjaCgwKQoJCQkJaWYgc2VsZi5xdWl0dGluZzoKCQkJCQkjIHJldHVybmluZyBOb25lIGlzIG5vdCBlbm91Z2gsIGEgZm9ybWVyIEJkYlF1aXQgZXhjZXB0aW9uCgkJCQkJIyBtaWdodCBoYXZlIGJlZW4gZWF0ZW4gYnkgdGhlIHByaW50IHN0YXRlbWVudAoJCQkJCXJhaXNlIGJkYi5CZGJRdWl0CgkJCQlpZiBldmVudCA9PSAnbGluZSc6CgkJCQkJcmV0dXJuIHNlbGYuZGlzcGF0Y2hfbGluZShmcmFtZSkKCQkJCWlmIGV2ZW50ID09ICdjYWxsJzoKCQkJCQlyZXR1cm4gc2VsZi5kaXNwYXRjaF9jYWxsKGZyYW1lLCBhcmcpCgkJCQlpZiBldmVudCA9PSAncmV0dXJuJzoKCQkJCQlyZXR1cm4gc2VsZi5kaXNwYXRjaF9yZXR1cm4oZnJhbWUsIGFyZykKCQkJCWlmIGV2ZW50ID09ICdleGNlcHRpb24nOgoJCQkJCXJldHVybiBzZWxmLmRpc3BhdGNoX2V4Y2VwdGlvbihmcmFtZSwgYXJnKQoJCQkJcHJpbnQgJ2JkYi5CZGIuZGlzcGF0Y2g6IHVua25vd24gZGVidWdnaW5nIGV2ZW50OicsIGBldmVudGAKCQkJCXJldHVybiBzZWxmLnRyYWNlX2Rpc3BhdGNoCgkJCWZpbmFsbHk6CgkJCQlNYWNPUy5FbmFibGVBcHBzd2l0Y2goLTEpCgkJZXhjZXB0IEtleWJvYXJkSW50ZXJydXB0OgoJCQlzZWxmLnNldF9zdGVwKCkKCQkJcmV0dXJuIHNlbGYudHJhY2VfZGlzcGF0Y2gKCQlleGNlcHQgYmRiLkJkYlF1aXQ6CgkJCWlmIHNlbGYuY29udGludWV3aXRob3V0ZGVidWdnZXI6CgkJCQlzZWxmLmNsZWFyX3RyYWNlZnVuY3MoKQoJCQkJcmV0dXJuCgkJCWVsc2U6CgkJCQlyYWlzZSBiZGIuQmRiUXVpdAoJCWV4Y2VwdDoKCQkJcHJpbnQgJ1hYWCBFeGNlcHRpb24gZHVyaW5nIGRlYnVnZ2VyIGludGVyYWN0aW9uLicsIFwKCQkJCQlzZWxmLmZvcm1hdGV4Y2VwdGlvbihzeXMuZXhjX3R5cGUsIHN5cy5leGNfdmFsdWUpCgkJCWltcG9ydCB0cmFjZWJhY2sKCQkJdHJhY2ViYWNrLnByaW50X2V4YygpCgkJCXJldHVybiBzZWxmLnRyYWNlX2Rpc3BhdGNoCgkKCWRlZiBkaXNwYXRjaF9jYWxsKHNlbGYsIGZyYW1lLCBhcmcpOgoJCWlmIG5vdCBzZWxmLnRyYWNlbWFnaWMgYW5kIFwKCQkJCWZyYW1lLmZfY29kZS5jb19uYW1lWzoyXSA9PSAnX18nID09IGZyYW1lLmZfY29kZS5jb19uYW1lWy0yOl0gYW5kIFwKCQkJCWZyYW1lLmZfY29kZS5jb19uYW1lIDw+ICdfX2luaXRfXyc6CgkJCXJldHVybgoJCWlmIHNlbGYuYm90ZnJhbWUgaXMgTm9uZToKCQkJIyBGaXJzdCBjYWxsIG9mIGRpc3BhdGNoIHNpbmNlIHJlc2V0KCkKCQkJc2VsZi5ib3RmcmFtZSA9IGZyYW1lLmZfYmFjawkjIHh4eCAhISEgYWRkZWQgZl9iYWNrCgkJCXJldHVybiBzZWxmLnRyYWNlX2Rpc3BhdGNoCgkJaWYgbm90IChzZWxmLnN0b3BfaGVyZShmcmFtZSkgb3Igc2VsZi5icmVha19hbnl3aGVyZShmcmFtZSkpOgoJCQkjIE5vIG5lZWQgdG8gdHJhY2UgdGhpcyBmdW5jdGlvbgoJCQlyZXR1cm4gIyBOb25lCgkJc2VsZi51c2VyX2NhbGwoZnJhbWUsIGFyZykKCQlpZiBzZWxmLnF1aXR0aW5nOgoJCQlyYWlzZSBiZGIuQmRiUXVpdAoJCXJldHVybiBzZWxmLnRyYWNlX2Rpc3BhdGNoCgkKCWRlZiBzZXRfY29udGludWUoc2VsZik6CgkJIyBEb24ndCBzdG9wIGV4Y2VwdCBhdCBicmVha3BvaW50cyBvciB3aGVuIGZpbmlzaGVkCgkJc2VsZi5zdG9wZnJhbWUgPSBzZWxmLmJvdGZyYW1lCgkJc2VsZi5yZXR1cm5mcmFtZSA9IE5vbmUKCQlzZWxmLnF1aXR0aW5nID0gMAoJCSMgdW5saWtlIGluIGJkYi9wZGIsIHRoZXJlJ3MgYSBjaGFuY2UgdGhhdCBicmVha3BvaW50cyBjaGFuZ2UgCgkJIyAqd2hpbGUqIGEgcHJvZ3JhbSAodGhpcyBwcm9ncmFtIDstKSBpcyBydW5uaW5nLiBJdCdzIGFjdHVhbGx5IHF1aXRlIGxpa2VseS4KCQkjIFNvIHdlIGRvbid0IGRlbGV0ZSBmcmFtZS5mX3RyYWNlIHVudGlsIHRoZSBib3R0b20gZnJhbWUgaWYgdGhlcmUgYXJlIG5vIGJyZWFrcG9pbnRzLgoJCglkZWYgc2V0X2JyZWFrKHNlbGYsIGZpbGVuYW1lLCBsaW5lbm8pOgoJCWlmIG5vdCBzZWxmLmJyZWFrcy5oYXNfa2V5KGZpbGVuYW1lKToKCQkJc2VsZi5icmVha3NbZmlsZW5hbWVdID0gW10KCQlsaXN0ID0gc2VsZi5icmVha3NbZmlsZW5hbWVdCgkJaWYgbGluZW5vIGluIGxpc3Q6CgkJCXJldHVybiAnVGhlcmUgaXMgYWxyZWFkeSBhIGJyZWFrcG9pbnQgdGhlcmUhJwoJCWxpc3QuYXBwZW5kKGxpbmVubykKCQlsaXN0LnNvcnQoKQkjIEkgd2FudCB0byBrZWVwIHRoZW0gbmVhdGx5IHNvcnRlZDsgZWFzaWVyIGZvciBkcmF3aW5nCgkJaWYgaGFzYXR0cihiZGIsICJCcmVha3BvaW50Iik6CgkJCSMgMS41LjJiMSBzcGVjaWZpYwoJCQlicCA9IGJkYi5CcmVha3BvaW50KGZpbGVuYW1lLCBsaW5lbm8sIDAsIE5vbmUpCgkJc2VsZi51cGRhdGVfYnJlYWtzKGZpbGVuYW1lKQoJCglkZWYgY2xlYXJfYnJlYWsoc2VsZiwgZmlsZW5hbWUsIGxpbmVubyk6CgkJYmRiLkJkYi5jbGVhcl9icmVhayhzZWxmLCBmaWxlbmFtZSwgbGluZW5vKQoJCXNlbGYudXBkYXRlX2JyZWFrcyhmaWxlbmFtZSkKCQoJZGVmIGNsZWFyX2FsbF9maWxlX2JyZWFrcyhzZWxmLCBmaWxlbmFtZSk6CgkJYmRiLkJkYi5jbGVhcl9hbGxfZmlsZV9icmVha3Moc2VsZiwgZmlsZW5hbWUpCgkJc2VsZi51cGRhdGVfYnJlYWtzKGZpbGVuYW1lKQoJCglkZWYgY2xlYXJfYWxsX2JyZWFrcyhzZWxmKToKCQliZGIuQmRiLmNsZWFyX2FsbF9icmVha3Moc2VsZikKCQlmb3IgZWRpdG9ycyBpbiBzZWxmLmVkaXRvcnMudmFsdWVzKCk6CgkJCWZvciBlZGl0b3IgaW4gZWRpdG9yczoKCQkJCWVkaXRvci5kcmF3YnJlYWtwb2ludHMoKQoJCgkjIHNwZWNpYWwKCQoJZGVmIHRvZ2dsZV9icmVhayhzZWxmLCBmaWxlbmFtZSwgbGluZW5vKToKCQlpZiBzZWxmLmdldF9icmVhayhmaWxlbmFtZSwgbGluZW5vKToKCQkJc2VsZi5jbGVhcl9icmVhayhmaWxlbmFtZSwgbGluZW5vKQoJCWVsc2U6CgkJCXNlbGYuc2V0X2JyZWFrKGZpbGVuYW1lLCBsaW5lbm8pCgkKCWRlZiBjbGVhcl9icmVha3NfYWJvdmUoc2VsZiwgZmlsZW5hbWUsIGFib3ZlKToKCQlpZiBub3Qgc2VsZi5icmVha3MuaGFzX2tleShmaWxlbmFtZSk6CgkJCXJldHVybiAnVGhlcmUgYXJlIG5vIGJyZWFrcG9pbnRzIGluIHRoYXQgZmlsZSEnCgkJZm9yIGxpbmVubyBpbiBzZWxmLmJyZWFrc1tmaWxlbmFtZV1bOl06CgkJCWlmIGxpbmVubyA+IGFib3ZlOgoJCQkJc2VsZi5icmVha3NbZmlsZW5hbWVdLnJlbW92ZShsaW5lbm8pCgkJaWYgbm90IHNlbGYuYnJlYWtzW2ZpbGVuYW1lXToKCQkJZGVsIHNlbGYuYnJlYWtzW2ZpbGVuYW1lXQoJCgkjIGVkaXRvciBzdHVmZgoJCglkZWYgdXBkYXRlX2JyZWFrcyhzZWxmLCBmaWxlbmFtZSk6CgkJaWYgc2VsZi5icmVha3N2aWV3ZXI6CgkJCXNlbGYuYnJlYWtzdmlld2VyLnVwZGF0ZSgpCgkJaWYgc2VsZi5lZGl0b3JzLmhhc19rZXkoZmlsZW5hbWUpOgoJCQlmb3IgZWRpdG9yIGluIHNlbGYuZWRpdG9yc1tmaWxlbmFtZV06CgkJCQlpZiBlZGl0b3IuX2RlYnVnZ2VyOgkjIFhYWAoJCQkJCWVkaXRvci5kcmF3YnJlYWtwb2ludHMoKQoJCQkJZWxzZToKCQkJCQlwcmludCAneHh4IGRlYWQgZWRpdG9yIScKCQoJZGVmIHVwZGF0ZV9hbGxicmVha3Moc2VsZik6CgkJaWYgc2VsZi5icmVha3N2aWV3ZXI6CgkJCXNlbGYuYnJlYWtzdmlld2VyLnVwZGF0ZSgpCgkJZm9yIGZpbGVuYW1lIGluIHNlbGYuYnJlYWtzLmtleXMoKToKCQkJaWYgc2VsZi5lZGl0b3JzLmhhc19rZXkoZmlsZW5hbWUpOgoJCQkJZm9yIGVkaXRvciBpbiBzZWxmLmVkaXRvcnNbZmlsZW5hbWVdOgoJCQkJCWlmIGVkaXRvci5fZGVidWdnZXI6CSMgWFhYCgkJCQkJCWVkaXRvci5kcmF3YnJlYWtwb2ludHMoKQoJCQkJCWVsc2U6CgkJCQkJCXByaW50ICd4eHggZGVhZCBlZGl0b3IhJwoJCglkZWYgcmVnaXN0ZXJfZWRpdG9yKHNlbGYsIGVkaXRvciwgZmlsZW5hbWUpOgoJCWlmIG5vdCBmaWxlbmFtZToKCQkJcmV0dXJuCgkJaWYgbm90IHNlbGYuZWRpdG9ycy5oYXNfa2V5KGZpbGVuYW1lKToKCQkJc2VsZi5lZGl0b3JzW2ZpbGVuYW1lXSA9IFtlZGl0b3JdCgkJZWxpZiBlZGl0b3Igbm90IGluIHNlbGYuZWRpdG9yc1tmaWxlbmFtZV06CgkJCXNlbGYuZWRpdG9yc1tmaWxlbmFtZV0uYXBwZW5kKGVkaXRvcikKCQoJZGVmIHVucmVnaXN0ZXJfZWRpdG9yKHNlbGYsIGVkaXRvciwgZmlsZW5hbWUpOgoJCWlmIG5vdCBmaWxlbmFtZToKCQkJcmV0dXJuCgkJdHJ5OgoJCQlzZWxmLmVkaXRvcnNbZmlsZW5hbWVdLnJlbW92ZShlZGl0b3IpCgkJCWlmIG5vdCBzZWxmLmVkaXRvcnNbZmlsZW5hbWVdOgoJCQkJZGVsIHNlbGYuZWRpdG9yc1tmaWxlbmFtZV0KCQkJCSMgaWYgdGhpcyB3YXMgYW4gdW50aXRsZWQgd2luZG93LCBjbGVhciB0aGUgYnJlYWtzLgoJCQkJaWYgZmlsZW5hbWVbOjFdID09ICc8JyBhbmQgZmlsZW5hbWVbLTE6XSA9PSAnPicgYW5kIFwKCQkJCQkJc2VsZi5icmVha3MuaGFzX2tleShmaWxlbmFtZSk6CgkJCQkJc2VsZi5jbGVhcl9hbGxfZmlsZV9icmVha3MoZmlsZW5hbWUpCgkJZXhjZXB0IChLZXlFcnJvciwgVmFsdWVFcnJvcik6CgkJCXBhc3MKCQkKCmNsYXNzIFNvdXJjZVZpZXdlcihXLlB5RWRpdG9yKToKCQoJZGVmIF9faW5pdF9fKHNlbGYsICphcmdzLCAqKmt3YXJncyk6CgkJYXBwbHkoVy5QeUVkaXRvci5fX2luaXRfXywgKHNlbGYsKSArIGFyZ3MsIGt3YXJncykKCQlzZWxmLmJpbmQoJzxjbGljaz4nLCBzZWxmLmNsaWNraW50ZXJjZXB0KQoJCglkZWYgY2xpY2tpbnRlcmNlcHQoc2VsZiwgcG9pbnQsIG1vZGlmaWVycyk6CgkJaWYgc2VsZi5fcGFyZW50d2luZG93Ll9jdXJyZW50d2lkZ2V0IDw+IHNlbGYgYW5kIG5vdCBzZWxmLnB0X2luX2JyZWFrcyhwb2ludCk6CgkJCXNlbGYuX3BhcmVudHdpbmRvdy54eHhfX19zZWxlY3Qoc2VsZikKCQkJcmV0dXJuIDEKCQoJZGVmIF9nZXR2aWV3cmVjdChzZWxmKToKCQlsLCB0LCByLCBiID0gc2VsZi5fYm91bmRzCgkJaWYgc2VsZi5fZGVidWdnZXI6CgkJCXJldHVybiAobCArIDEyLCB0ICsgMiwgciAtIDEsIGIgLSAyKQoJCWVsc2U6CgkJCXJldHVybiAobCArIDUsIHQgKyAyLCByIC0gMSwgYiAtIDIpCgkKCWRlZiBzZWxlY3Qoc2VsZiwgb25vZmYsIGlzY2xpY2sgPSAwKToKCQlpZiBXLlNlbGVjdGFibGVXaWRnZXQuc2VsZWN0KHNlbGYsIG9ub2ZmKToKCQkJcmV0dXJuCgkJc2VsZi5TZXRQb3J0KCkKCQkjaWYgb25vZmY6CgkJIwlzZWxmLnRlZC5XRUFjdGl2YXRlKCkKCQkjZWxzZToKCQkjCXNlbGYudGVkLldFRGVhY3RpdmF0ZSgpCgkJc2VsZi5kcmF3c2VsZnJhbWUob25vZmYpCgkKCWRlZiBkcmF3c2VsZnJhbWUoc2VsZiwgb25vZmYpOgoJCXBhc3MKCgpjbGFzcyBCcmVha3BvaW50c1ZpZXdlcjoKCQoJZGVmIF9faW5pdF9fKHNlbGYsIGRlYnVnZ2VyKToKCQlzZWxmLmRlYnVnZ2VyID0gZGVidWdnZXIKCQlpbXBvcnQgTGlzdHMKCQlzZWxmLncgPSBXLldpbmRvdygoMzAwLCAyNTApLCAnQnJlYWtwb2ludHMnLCBtaW5zaXplID0gKDIwMCwgMjAwKSkKCQlzZWxmLncucGFuZXMgPSBXLkhvcml6b250YWxQYW5lcygoOCwgOCwgLTgsIC0zMiksICgwLjMsIDAuNykpCgkJc2VsZi53LnBhbmVzLmZpbGVzID0gVy5MaXN0KE5vbmUsIGNhbGxiYWNrID0gc2VsZi5maWxlaGl0KQkJIywgZmxhZ3MgPSBMaXN0cy5sT25seU9uZSkKCQlzZWxmLncucGFuZXMuZ3IgPSBXLkdyb3VwKE5vbmUpCgkJc2VsZi53LnBhbmVzLmdyLmJyZWFrcyA9IFcuTGlzdCgoMCwgMCwgLTEzMCwgMCksIGNhbGxiYWNrID0gc2VsZi5saW5laGl0KQkjLCBmbGFncyA9IExpc3RzLmxPbmx5T25lKQoJCXNlbGYudy5wYW5lcy5nci5vcGVuYnV0dG9uID0gVy5CdXR0b24oKC04MCwgNCwgMCwgMTYpLCAnVmlld4onLCBzZWxmLm9wZW5idXR0b25oaXQpCgkJc2VsZi53LnBhbmVzLmdyLmRlbGV0ZWJ1dHRvbiA9IFcuQnV0dG9uKCgtODAsIDI4LCAwLCAxNiksICdEZWxldGUnLCBzZWxmLmRlbGV0ZWJ1dHRvbmhpdCkKCQkKCQlzZWxmLncuYmluZCgnPGNsb3NlPicsIHNlbGYuY2xvc2UpCgkJc2VsZi53LmJpbmQoJ2JhY2tzcGFjZScsIHNlbGYudy5wYW5lcy5nci5kZWxldGVidXR0b24ucHVzaCkKCQkKCQlzZWxmLnNldHVwKCkKCQlzZWxmLncub3BlbigpCgkJc2VsZi53LnBhbmVzLmdyLm9wZW5idXR0b24uZW5hYmxlKDApCgkJc2VsZi53LnBhbmVzLmdyLmRlbGV0ZWJ1dHRvbi5lbmFibGUoMCkKCQlzZWxmLmN1cmZpbGUgPSBOb25lCgkKCWRlZiBkZWxldGVidXR0b25oaXQoc2VsZik6CgkJaWYgc2VsZi53Ll9jdXJyZW50d2lkZ2V0ID09IHNlbGYudy5wYW5lcy5maWxlczoKCQkJc2VsZi5kZWxfZmlsZW5hbWUoKQoJCWVsc2U6CgkJCXNlbGYuZGVsX251bWJlcigpCgkJc2VsZi5jaGVja2J1dHRvbnMoKQoJCglkZWYgZGVsX251bWJlcihzZWxmKToKCQlpZiBzZWxmLmN1cmZpbGUgaXMgTm9uZToKCQkJcmV0dXJuCgkJc2VsID0gc2VsZi53LnBhbmVzLmdyLmJyZWFrcy5nZXRzZWxlY3RlZG9iamVjdHMoKQoJCWZvciBsaW5lbm8gaW4gc2VsOgoJCQlzZWxmLmRlYnVnZ2VyLmNsZWFyX2JyZWFrKHNlbGYuY3VyZmlsZSwgbGluZW5vKQoJCglkZWYgZGVsX2ZpbGVuYW1lKHNlbGYpOgoJCXNlbCA9IHNlbGYudy5wYW5lcy5maWxlcy5nZXRzZWxlY3RlZG9iamVjdHMoKQoJCWZvciBmaWxlbmFtZSBpbiBzZWw6CgkJCXNlbGYuZGVidWdnZXIuY2xlYXJfYWxsX2ZpbGVfYnJlYWtzKGZpbGVuYW1lKQoJCXNlbGYuZGVidWdnZXIudXBkYXRlX2FsbGJyZWFrcygpCgkKCWRlZiBzZXR1cChzZWxmKToKCQlmaWxlcyA9IHNlbGYuZGVidWdnZXIuYnJlYWtzLmtleXMoKQoJCWZpbGVzLnNvcnQoKQoJCXNlbGYudy5wYW5lcy5maWxlcy5zZXQoZmlsZXMpCgkKCWRlZiBjbG9zZShzZWxmKToKCQlzZWxmLmRlYnVnZ2VyLmJyZWFrc3ZpZXdlciA9IE5vbmUKCQlzZWxmLmRlYnVnZ2VyID0gTm9uZQoJCglkZWYgdXBkYXRlKHNlbGYpOgoJCXNlbCA9IHNlbGYudy5wYW5lcy5maWxlcy5nZXRzZWxlY3RlZG9iamVjdHMoKQoJCXNlbGYuc2V0dXAoKQoJCXNlbGYudy5wYW5lcy5maWxlcy5zZXRzZWxlY3RlZG9iamVjdHMoc2VsKQoJCXNlbCA9IHNlbGYudy5wYW5lcy5maWxlcy5nZXRzZWxlY3Rpb24oKQoJCWlmIGxlbihzZWwpID09IDAgYW5kIHNlbGYuY3VyZmlsZToKCQkJc2VsZi53LnBhbmVzLmZpbGVzLnNldHNlbGVjdGVkb2JqZWN0cyhbc2VsZi5jdXJmaWxlXSkKCQlzZWxmLmZpbGVoaXQoMCkKCQoJZGVmIHNlbGVjdChzZWxmKToKCQlzZWxmLncuc2VsZWN0KCkKCQoJZGVmIHNlbGVjdGZpbGUoc2VsZiwgZmlsZSk6CgkJc2VsZi53LnBhbmVzLmZpbGVzLnNldHNlbGVjdGVkb2JqZWN0cyhbZmlsZV0pCgkJc2VsZi5maWxlaGl0KDApCQkJCgkKCWRlZiBvcGVuYnV0dG9uaGl0KHNlbGYpOgoJCXNlbGYuZmlsZWhpdCgxKQoJCglkZWYgZmlsZWhpdChzZWxmLCBpc2RibCk6CgkJc2VsID0gc2VsZi53LnBhbmVzLmZpbGVzLmdldHNlbGVjdGVkb2JqZWN0cygpCgkJaWYgaXNkYmw6CgkJCWZvciBmaWxlbmFtZSBpbiBzZWw6CgkJCQlsaW5lbm8gPSBOb25lCgkJCQlpZiBmaWxlbmFtZSA9PSBzZWxmLmN1cmZpbGU6CgkJCQkJbGluZXNlbCA9IHNlbGYudy5wYW5lcy5nci5icmVha3MuZ2V0c2VsZWN0ZWRvYmplY3RzKCkKCQkJCQlpZiBsaW5lc2VsOgoJCQkJCQlsaW5lbm8gPSBsaW5lc2VsWy0xXQoJCQkJCWVsaWYgc2VsZi53LnBhbmVzLmdyLmJyZWFrczoKCQkJCQkJbGluZW5vID0gc2VsZi53LnBhbmVzLmdyLmJyZWFrc1swXQoJCQkJZWRpdG9yID0gc2VsZi53Ll9wYXJlbnR3aW5kb3cucGFyZW50Lm9wZW5zY3JpcHQoZmlsZW5hbWUsIGxpbmVubykKCQkJCWVkaXRvci5zaG93YnJlYWtwb2ludHMoMSkKCQkJcmV0dXJuCgkJaWYgbGVuKHNlbCkgPT0gMToKCQkJZmlsZSA9IHNlbFswXQoJCQlmaWxlYnJlYWtzID0gc2VsZi5kZWJ1Z2dlci5icmVha3NbZmlsZV1bOl0KCQkJaWYgc2VsZi5jdXJmaWxlID09IGZpbGU6CgkJCQlsaW5lc2VsID0gc2VsZi53LnBhbmVzLmdyLmJyZWFrcy5nZXRzZWxlY3RlZG9iamVjdHMoKQoJCQlzZWxmLncucGFuZXMuZ3IuYnJlYWtzLnNldChmaWxlYnJlYWtzKQoJCQlpZiBzZWxmLmN1cmZpbGUgPT0gZmlsZToKCQkJCXNlbGYudy5wYW5lcy5nci5icmVha3Muc2V0c2VsZWN0ZWRvYmplY3RzKGxpbmVzZWwpCgkJCXNlbGYuY3VyZmlsZSA9IGZpbGUKCQllbHNlOgoJCQlpZiBsZW4oc2VsKSA8PiAwOgoJCQkJc2VsZi5jdXJmaWxlID0gTm9uZQoJCQlzZWxmLncucGFuZXMuZ3IuYnJlYWtzLnNldChbXSkKCQlzZWxmLmNoZWNrYnV0dG9ucygpCgkKCWRlZiBsaW5laGl0KHNlbGYsIGlzZGJsKToKCQlpZiBpc2RibDoKCQkJZmlsZXMgPSBzZWxmLncucGFuZXMuZmlsZXMuZ2V0c2VsZWN0ZWRvYmplY3RzKCkKCQkJaWYgbGVuKGZpbGVzKSA8PiAxOgoJCQkJcmV0dXJuCgkJCWZpbGVuYW1lID0gZmlsZXNbMF0KCQkJbGluZW5vcyA9IHNlbGYudy5wYW5lcy5nci5icmVha3MuZ2V0c2VsZWN0ZWRvYmplY3RzKCkKCQkJaWYgbm90IGxpbmVub3M6CgkJCQlyZXR1cm4KCQkJbGluZW5vID0gbGluZW5vc1stMV0KCQkJZWRpdG9yID0gc2VsZi53Ll9wYXJlbnR3aW5kb3cucGFyZW50Lm9wZW5zY3JpcHQoZmlsZW5hbWUsIGxpbmVubykKCQkJZWRpdG9yLnNob3dicmVha3BvaW50cygxKQoJCXNlbGYuY2hlY2tidXR0b25zKCkKCQoJZGVmIGNoZWNrYnV0dG9ucyhzZWxmKToKCQlpZiBzZWxmLncucGFuZXMuZmlsZXMuZ2V0c2VsZWN0aW9uKCk6CgkJCXNlbGYudy5wYW5lcy5nci5vcGVuYnV0dG9uLmVuYWJsZSgxKQoJCQlzZWxmLncuX3BhcmVudHdpbmRvdy5zZXRkZWZhdWx0YnV0dG9uKHNlbGYudy5wYW5lcy5nci5vcGVuYnV0dG9uKQoJCQlpZiBzZWxmLncuX2N1cnJlbnR3aWRnZXQgPT0gc2VsZi53LnBhbmVzLmZpbGVzOgoJCQkJaWYgc2VsZi53LnBhbmVzLmZpbGVzLmdldHNlbGVjdGlvbigpOgoJCQkJCXNlbGYudy5wYW5lcy5nci5kZWxldGVidXR0b24uZW5hYmxlKDEpCgkJCQllbHNlOgoJCQkJCXNlbGYudy5wYW5lcy5nci5kZWxldGVidXR0b24uZW5hYmxlKDApCgkJCWVsc2U6CgkJCQlpZiBzZWxmLncucGFuZXMuZ3IuYnJlYWtzLmdldHNlbGVjdGlvbigpOgoJCQkJCXNlbGYudy5wYW5lcy5nci5kZWxldGVidXR0b24uZW5hYmxlKDEpCgkJCQllbHNlOgoJCQkJCXNlbGYudy5wYW5lcy5nci5kZWxldGVidXR0b24uZW5hYmxlKDApCgkJZWxzZToKCQkJc2VsZi53LnBhbmVzLmdyLm9wZW5idXR0b24uZW5hYmxlKDApCgkJCXNlbGYudy5wYW5lcy5nci5kZWxldGVidXR0b24uZW5hYmxlKDApCgoKY2xhc3MgVHJhY2luZ01vbml0b3IoVy5XaWRnZXQpOgoJCglkZWYgX19pbml0X18oc2VsZiwgKmFyZ3MsICoqa3dhcmdzKToKCQlhcHBseShXLldpZGdldC5fX2luaXRfXywgKHNlbGYsKSArIGFyZ3MsIGt3YXJncykKCQlzZWxmLnN0YXRlID0gMAoJCglkZWYgdG9nZ2xlKHNlbGYpOgoJCWlmIGhhc2F0dHIoc2VsZiwgIl9wYXJlbnR3aW5kb3ciKSBhbmQgc2VsZi5fcGFyZW50d2luZG93IGlzIG5vdCBOb25lOgoJCQlzZWxmLnN0YXRlID0gc2VsZi5zdGF0ZSAlIDIgKyAxCgkJCXBvcnQgPSBRZC5HZXRQb3J0KCkKCQkJc2VsZi5TZXRQb3J0KCkKCQkJc2VsZi5kcmF3KCkKCQkJUWQuU2V0UG9ydChwb3J0KQoJCglkZWYgcmVzZXQoc2VsZik6CgkJaWYgc2VsZi5fcGFyZW50d2luZG93OgoJCQlzZWxmLnN0YXRlID0gMAoJCQlwb3J0ID0gUWQuR2V0UG9ydCgpCgkJCXNlbGYuU2V0UG9ydCgpCgkJCXNlbGYuZHJhdygpCgkJCVFkLlNldFBvcnQocG9ydCkKCQoJZGVmIGRyYXcoc2VsZiwgdmlzUmduID0gTm9uZSk6CgkJaWYgc2VsZi5zdGF0ZSA9PSAyOgoJCQlRZC5QYWludE92YWwoc2VsZi5fYm91bmRzKQoJCWVsc2U6CgkJCVFkLkVyYXNlT3ZhbChzZWxmLl9ib3VuZHMpCgoKIyBjb252ZW5pZW5jZSBmdW5jcwoKZGVmIHBvc3Rtb3J0ZW0oZXhjX3R5cGUsIGV4Y192YWx1ZSwgdGIpOgoJZCA9IGdldGRlYnVnZ2VyKCkKCWQucG9zdG1vcnRlbShleGNfdHlwZSwgZXhjX3ZhbHVlLCB0YikKCmRlZiBzdGFydChib3R0b21mcmFtZSA9IE5vbmUpOgoJZCA9IGdldGRlYnVnZ2VyKCkKCWQuc3RhcnQoYm90dG9tZnJhbWUpCgpkZWYgc3RhcnRmcm9taGVyZSgpOgoJZCA9IGdldGRlYnVnZ2VyKCkKCXRyeToKCQlyYWlzZSAnc3BhbScKCWV4Y2VwdDoKCQlmcmFtZSA9IHN5cy5leGNfdHJhY2ViYWNrLnRiX2ZyYW1lLmZfYmFjawoJZC5zdGFydChmcmFtZSkKCmRlZiBzdGFydGZyb21ib3R0b20oKToKCWQgPSBnZXRkZWJ1Z2dlcigpCglkLnN0YXJ0KF9nZXRib3R0b21mcmFtZSgpLCAxKQoKZGVmIHN0b3AoKToKCWQgPSBnZXRkZWJ1Z2dlcigpCglkLnN0b3AoKQoKZGVmIGNvbnQoKToKCXN5cy5zZXR0cmFjZShOb25lKQoJZCA9IGdldGRlYnVnZ2VyKCkKCWQuc2V0X2NvbnRpbnVlX3dpdGhvdXRfZGVidWdnZXIoKQoKZGVmIF9nZXRib3R0b21mcmFtZSgpOgoJdHJ5OgoJCXJhaXNlICdzcGFtJwoJZXhjZXB0OgoJCXBhc3MKCWZyYW1lID0gc3lzLmV4Y190cmFjZWJhY2sudGJfZnJhbWUKCXdoaWxlIDE6CgkJaWYgZnJhbWUuZl9jb2RlLmNvX25hbWUgPT0gJ21haW5sb29wJyBvciBmcmFtZS5mX2JhY2sgaXMgTm9uZToKCQkJYnJlYWsKCQlmcmFtZSA9IGZyYW1lLmZfYmFjawoJcmV0dXJuIGZyYW1lCgpfZGVidWdnZXIgPSBOb25lCgpkZWYgZ2V0ZGVidWdnZXIoKToKCWlmIG5vdCBfX2RlYnVnX186CgkJcmFpc2UgVy5BbGVydEVycm9yLCAiQ2FuuXQgZGVidWcgaW4gs09wdGltaXplIGJ5dGVjb2RlsiBtb2RlLlxyKHNlZSCzRGVmYXVsdCBzdGFydHVwIG9wdGlvbnOyIGluIEVkaXRQeXRob25QcmVmZXJlbmNlcykiCglnbG9iYWwgX2RlYnVnZ2VyCglpZiBfZGVidWdnZXIgaXMgTm9uZToKCQlfZGVidWdnZXIgPSBEZWJ1Z2dlcigpCglyZXR1cm4gX2RlYnVnZ2VyCg==