ZGlmZiAtLWdpdCBhL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvUHl0aG9uSURFTWFpbi5weSBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvUHl0aG9uSURFTWFpbi5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi40YjE0YmNkCi0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9QeXRob25JREVNYWluLnB5CkBAIC0wLDAgKzEsMjI0IEBACisjIGNvcHlyaWdodCAxOTk3IEp1c3QgdmFuIFJvc3N1bSwgTGV0dGVycm9yLiBqdXN0QGtub3dhcmUubmwKKworaW1wb3J0IFNwbGFzaAorCitpbXBvcnQgRnJhbWVXb3JrCitpbXBvcnQgV0ZyYW1lV29ya1BhdGNoCitpbXBvcnQgV2luCitpbXBvcnQgVworaW1wb3J0IG9zCitpbXBvcnQgbWFjZnMKKworY2xhc3MgUHl0aG9uSURFKFdGcmFtZVdvcmtQYXRjaC5BcHBsaWNhdGlvbik6CisJCisJZGVmIF9faW5pdF9fKHNlbGYpOgorCQlzZWxmLnByZWZmaWxlcGF0aCA9ICI6UHl0aG9uOlB5dGhvbklERSBwcmVmZXJlbmNlcyIKKwkJV0ZyYW1lV29ya1BhdGNoLkFwcGxpY2F0aW9uLl9faW5pdF9fKHNlbGYsICdQeXRoJykKKwkJaW1wb3J0IEFFLCBBcHBsZUV2ZW50cworCQkKKwkJQUUuQUVJbnN0YWxsRXZlbnRIYW5kbGVyKEFwcGxlRXZlbnRzLmtDb3JlRXZlbnRDbGFzcywgQXBwbGVFdmVudHMua0FFT3BlbkFwcGxpY2F0aW9uLCAKKwkJCQlzZWxmLmlnbm9yZWV2ZW50KQorCQlBRS5BRUluc3RhbGxFdmVudEhhbmRsZXIoQXBwbGVFdmVudHMua0NvcmVFdmVudENsYXNzLCBBcHBsZUV2ZW50cy5rQUVQcmludERvY3VtZW50cywgCisJCQkJc2VsZi5pZ25vcmVldmVudCkKKwkJQUUuQUVJbnN0YWxsRXZlbnRIYW5kbGVyKEFwcGxlRXZlbnRzLmtDb3JlRXZlbnRDbGFzcywgQXBwbGVFdmVudHMua0FFT3BlbkRvY3VtZW50cywgCisJCQkJc2VsZi5vcGVuZG9jc2V2ZW50KQorCQlBRS5BRUluc3RhbGxFdmVudEhhbmRsZXIoQXBwbGVFdmVudHMua0NvcmVFdmVudENsYXNzLCBBcHBsZUV2ZW50cy5rQUVRdWl0QXBwbGljYXRpb24sIAorCQkJCXNlbGYucXVpdGV2ZW50KQorCQlpbXBvcnQgUHlDb25zb2xlLCBQeUVkaXQKKwkJU3BsYXNoLndhaXQoKQorCQlQeUNvbnNvbGUuaW5zdGFsbGNvbnNvbGUoKQorCQlQeUNvbnNvbGUuaW5zdGFsbG91dHB1dCgpCisJCWltcG9ydCBzeXMKKwkJZm9yIHBhdGggaW4gc3lzLmFyZ3ZbMTpdOgorCQkJc2VsZi5vcGVuZG9jKHBhdGgpCisJCXNlbGYubWFpbmxvb3AoKQorCQorCWRlZiBtYWtldXNlcm1lbnVzKHNlbGYpOgorCQltID0gV0ZyYW1lV29ya1BhdGNoLk1lbnUoc2VsZi5tZW51YmFyLCAiRmlsZSIpCisJCW5ld2l0ZW0gPSBGcmFtZVdvcmsuTWVudUl0ZW0obSwgIk5ldyIsICJOIiwgJ25ldycpCisJCW9wZW5pdGVtID0gRnJhbWVXb3JrLk1lbnVJdGVtKG0sICJPcGVuiiIsICJPIiwgJ29wZW4nKQorCQlGcmFtZVdvcmsuU2VwYXJhdG9yKG0pCisJCWNsb3NlaXRlbSA9IEZyYW1lV29yay5NZW51SXRlbShtLCAiQ2xvc2UiLCAiVyIsICdjbG9zZScpCisJCXNhdmVpdGVtID0gRnJhbWVXb3JrLk1lbnVJdGVtKG0sICJTYXZlIiwgIlMiLCAnc2F2ZScpCisJCXNhdmVhc2l0ZW0gPSBGcmFtZVdvcmsuTWVudUl0ZW0obSwgIlNhdmUgYXOKIiwgTm9uZSwgJ3NhdmVfYXMnKQorCQlGcmFtZVdvcmsuU2VwYXJhdG9yKG0pCisJCXF1aXRpdGVtID0gRnJhbWVXb3JrLk1lbnVJdGVtKG0sICJRdWl0IiwgIlEiLCAncXVpdCcpCisJCQorCQltID0gV0ZyYW1lV29ya1BhdGNoLk1lbnUoc2VsZi5tZW51YmFyLCAiRWRpdCIpCisJCXVuZG9pdGVtID0gRnJhbWVXb3JrLk1lbnVJdGVtKG0sICJVbmRvIiwgJ1onLCAidW5kbyIpCisJCUZyYW1lV29yay5TZXBhcmF0b3IobSkKKwkJY3V0aXRlbSA9IEZyYW1lV29yay5NZW51SXRlbShtLCAiQ3V0IiwgJ1gnLCAiY3V0IikKKwkJY29weWl0ZW0gPSBGcmFtZVdvcmsuTWVudUl0ZW0obSwgIkNvcHkiLCAiQyIsICJjb3B5IikKKwkJcGFzdGVpdGVtID0gRnJhbWVXb3JrLk1lbnVJdGVtKG0sICJQYXN0ZSIsICJWIiwgInBhc3RlIikKKwkJRnJhbWVXb3JrLk1lbnVJdGVtKG0sICJDbGVhciIsIE5vbmUsICAiY2xlYXIiKQorCQlGcmFtZVdvcmsuU2VwYXJhdG9yKG0pCisJCXNlbGFsbGl0ZW0gPSBGcmFtZVdvcmsuTWVudUl0ZW0obSwgIlNlbGVjdCBhbGwiLCAiQSIsICJzZWxlY3RhbGwiKQorCQlzZWxsaW5laXRlbSA9IEZyYW1lV29yay5NZW51SXRlbShtLCAiU2VsZWN0IGxpbmUiLCAiTCIsICJzZWxlY3RsaW5lIikKKwkJRnJhbWVXb3JrLlNlcGFyYXRvcihtKQorCQlmaW5kaXRlbSA9IEZyYW1lV29yay5NZW51SXRlbShtLCAiRmluZIoiLCAiRiIsICJmaW5kIikKKwkJZmluZGFnYWluaXRlbSA9IEZyYW1lV29yay5NZW51SXRlbShtLCAiRmluZCBhZ2FpbiIsICdHJywgImZpbmRuZXh0IikKKwkJZW50ZXJzZWxpdGVtID0gRnJhbWVXb3JrLk1lbnVJdGVtKG0sICJFbnRlciBzZWFyY2ggc3RyaW5nIiwgIkUiLCAiZW50ZXJzZWFyY2hzdHJpbmciKQorCQlyZXBsYWNlaXRlbSA9IEZyYW1lV29yay5NZW51SXRlbShtLCAiUmVwbGFjZSIsIE5vbmUsICJyZXBsYWNlIikKKwkJcmVwbGFjZWZpbmRpdGVtID0gRnJhbWVXb3JrLk1lbnVJdGVtKG0sICJSZXBsYWNlICYgZmluZCBhZ2FpbiIsICdUJywgInJlcGxhY2VmaW5kIikKKwkJRnJhbWVXb3JrLlNlcGFyYXRvcihtKQorCQlzaGlmdGxlZnRpdGVtID0gRnJhbWVXb3JrLk1lbnVJdGVtKG0sICJTaGlmdCBsZWZ0IiwgIlsiLCAic2hpZnRsZWZ0IikKKwkJc2hpZnRyaWdodGl0ZW0gPSBGcmFtZVdvcmsuTWVudUl0ZW0obSwgIlNoaWZ0IHJpZ2h0IiwgIl0iLCAic2hpZnRyaWdodCIpCisJCQorCQltID0gV0ZyYW1lV29ya1BhdGNoLk1lbnUoc2VsZi5tZW51YmFyLCAiUHl0aG9uIikKKwkJcnVuaXRlbSA9IEZyYW1lV29yay5NZW51SXRlbShtLCAiUnVuIHdpbmRvdyIsICJSIiwgJ3J1bicpCisJCXJ1bnNlbGl0ZW0gPSBGcmFtZVdvcmsuTWVudUl0ZW0obSwgIlJ1biBzZWxlY3Rpb24iLCBOb25lLCAncnVuc2VsZWN0aW9uJykKKwkJRnJhbWVXb3JrLlNlcGFyYXRvcihtKQorCQltb2RpdGVtID0gRnJhbWVXb3JrLk1lbnVJdGVtKG0sICJNb2R1bGUgYnJvd3NlcooiLCAiTSIsIHNlbGYuZG9tZW51X21vZHVsZWJyb3dzZXIpCisJCUZyYW1lV29yay5TZXBhcmF0b3IobSkKKwkJbW0gPSBGcmFtZVdvcmsuU3ViTWVudShtLCAiUHJlZmVyZW5jZXMiKQorCQlGcmFtZVdvcmsuTWVudUl0ZW0obW0sICJTZXQgU2NyaXB0cyBmb2xkZXKKIiwgTm9uZSwgc2VsZi5kb19zZXRzY3JpcHRzZm9sZGVyKQorCQkKKwkJc2VsZi5vcGVud2luZG93c21lbnUgPSBXRnJhbWVXb3JrUGF0Y2guTWVudShzZWxmLm1lbnViYXIsICdXaW5kb3dzJykKKwkJc2VsZi5tYWtlb3BlbndpbmRvd3NtZW51KCkKKwkJc2VsZi5fbWVudXN0b2NoZWNrID0gW2Nsb3NlaXRlbSwgc2F2ZWl0ZW0sIHNhdmVhc2l0ZW0sCisJCQkJdW5kb2l0ZW0sIGN1dGl0ZW0sIGNvcHlpdGVtLCBwYXN0ZWl0ZW0sIAorCQkJCXNlbGFsbGl0ZW0sIHNlbGxpbmVpdGVtLCAKKwkJCQlmaW5kaXRlbSwgZmluZGFnYWluaXRlbSwgZW50ZXJzZWxpdGVtLCByZXBsYWNlaXRlbSwgcmVwbGFjZWZpbmRpdGVtLAorCQkJCXNoaWZ0bGVmdGl0ZW0sIHNoaWZ0cmlnaHRpdGVtLCAKKwkJCQlydW5pdGVtLCBydW5zZWxpdGVtXQorCQkKKwkJcHJlZnMgPSBzZWxmLmdldHByZWZzKCkKKwkJaWYgcHJlZnMuc2NyaXB0c2ZvbGRlcjoKKwkJCWZzcywgZnNzX2NoYW5nZWQgPSBtYWNmcy5SYXdBbGlhcyhwcmVmcy5zY3JpcHRzZm9sZGVyKS5SZXNvbHZlKCkKKwkJCXNlbGYuc2NyaXB0c2ZvbGRlciA9IGZzcy5OZXdBbGlhcygpCisJCQlwcmVmcy5zY3JpcHRzZm9sZGVyID0gc2VsZi5zY3JpcHRzZm9sZGVyLmRhdGEKKwkJCXNlbGYuc2NyaXB0c2ZvbGRlcm1vZHRpbWUgPSBmc3MuR2V0RGF0ZXMoKVsxXQorCQllbHNlOgorCQkJcGF0aCA9IG9zLnBhdGguam9pbihvcy5nZXRjd2QoKSwgJ1NjcmlwdHMnKQorCQkJaWYgbm90IG9zLnBhdGguZXhpc3RzKHBhdGgpOgorCQkJCW9zLm1rZGlyKHBhdGgpCisJCQlmc3MgPSBtYWNmcy5GU1NwZWMocGF0aCkKKwkJCXNlbGYuc2NyaXB0c2ZvbGRlciA9IGZzcy5OZXdBbGlhcygpCisJCQlzZWxmLnNjcmlwdHNmb2xkZXJtb2R0aW1lID0gZnNzLkdldERhdGVzKClbMV0KKwkJc2VsZi5fc2NyaXB0cyA9IHt9CisJCXNlbGYuc2NyaXB0c21lbnUgPSBOb25lCisJCXNlbGYubWFrZXNjcmlwdHNtZW51KCkKKwkKKwlkZWYgcXVpdGV2ZW50KHNlbGYsIHRoZUFwcGxlRXZlbnQsIHRoZVJlcGx5KToKKwkJaW1wb3J0IEFFCisJCUFFLkFFSW50ZXJhY3RXaXRoVXNlcig1MDAwMDAwMCkKKwkJc2VsZi5fcXVpdCgpCisJCisJZGVmIHN1c3BlbmRyZXN1bWUoc2VsZiwgb25vZmYpOgorCQlpZiBvbm9mZjoKKwkJCWZzcywgZnNzX2NoYW5nZWQgPSBzZWxmLnNjcmlwdHNmb2xkZXIuUmVzb2x2ZSgpCisJCQltb2R0aW1lID0gZnNzLkdldERhdGVzKClbMV0KKwkJCWlmIHNlbGYuc2NyaXB0c2ZvbGRlcm1vZHRpbWUgPD4gbW9kdGltZSBvciBmc3NfY2hhbmdlZDoKKwkJCQlzZWxmLnNjcmlwdHNmb2xkZXJtb2R0aW1lID0gbW9kdGltZQorCQkJCVcuU2V0Q3Vyc29yKCd3YXRjaCcpCisJCQkJc2VsZi5tYWtlc2NyaXB0c21lbnUoKQorCQorCWRlZiBpZ25vcmVldmVudChzZWxmLCB0aGVBcHBsZUV2ZW50LCB0aGVSZXBseSk6CisJCXBhc3MKKwkKKwlkZWYgb3BlbmRvY3NldmVudChzZWxmLCB0aGVBcHBsZUV2ZW50LCB0aGVSZXBseSk6CisJCVcuU2V0Q3Vyc29yKCd3YXRjaCcpCisJCWltcG9ydCBhZXRvb2xzCisJCXBhcmFtZXRlcnMsIGFyZ3MgPSBhZXRvb2xzLnVucGFja2V2ZW50KHRoZUFwcGxlRXZlbnQpCisJCWRvY3MgPSBwYXJhbWV0ZXJzWyctLS0tJ10KKwkJaWYgdHlwZShkb2NzKSA8PiB0eXBlKFtdKToKKwkJCWRvY3MgPSBbZG9jc10KKwkJZm9yIGRvYyBpbiBkb2NzOgorCQkJZnNzLCBhID0gZG9jLlJlc29sdmUoKQorCQkJcGF0aCA9IGZzcy5hc19wYXRobmFtZSgpCisJCQlzZWxmLm9wZW5kb2MocGF0aCkKKwkKKwlkZWYgb3BlbmRvYyhzZWxmLCBwYXRoKToKKwkJZmNyZWF0b3IsIGZ0eXBlID0gbWFjZnMuRlNTcGVjKHBhdGgpLkdldENyZWF0b3JUeXBlKCkKKwkJaWYgZnR5cGUgPT0gJ1RFWFQnOgorCQkJc2VsZi5vcGVuc2NyaXB0KHBhdGgpCisJCWVsc2U6CisJCQlXLk1lc3NhZ2UoIkNhbrl0IG9wZW4gZmlsZSBvZiB0eXBlICclcycuIiAlIGZ0eXBlKQorCQorCWRlZiBnZXRhYm91dHRleHQoc2VsZik6CisJCXJldHVybiAiQWJvdXQgUHl0aG9uIElERYoiCisJCisJZGVmIGRvX2Fib3V0KHNlbGYsIGlkLCBpdGVtLCB3aW5kb3csIGV2ZW50KToKKwkJU3BsYXNoLmFib3V0KCkKKwkKKwlkZWYgZG9fc2V0c2NyaXB0c2ZvbGRlcihzZWxmLCAqYXJncyk6CisJCWZzcywgb2sgPSBtYWNmcy5HZXREaXJlY3RvcnkoIlNlbGVjdCBTY3JpcHRzIEZvbGRlciIpCisJCWlmIG9rOgorCQkJcHJlZnMgPSBzZWxmLmdldHByZWZzKCkKKwkJCWFsaXMgPSBmc3MuTmV3QWxpYXMoKQorCQkJcHJlZnMuc2NyaXB0c2ZvbGRlciA9IGFsaXMuZGF0YQorCQkJc2VsZi5zY3JpcHRzZm9sZGVyID0gYWxpcworCQkJc2VsZi5tYWtlc2NyaXB0c21lbnUoKQorCQkJcHJlZnMuc2F2ZSgpCisJCisJZGVmIGRvbWVudV9tb2R1bGVicm93c2VyKHNlbGYsICphcmdzKToKKwkJVy5TZXRDdXJzb3IoJ3dhdGNoJykKKwkJaW1wb3J0IE1vZHVsZUJyb3dzZXIKKwkJTW9kdWxlQnJvd3Nlci5Nb2R1bGVCcm93c2VyKCkKKwkKKwlkZWYgZG9tZW51X29wZW4oc2VsZiwgKmFyZ3MpOgorCQlmc3MsIG9rID0gbWFjZnMuU3RhbmRhcmRHZXRGaWxlKCJURVhUIikKKwkJaWYgb2s6CisJCQlzZWxmLm9wZW5zY3JpcHQoZnNzLmFzX3BhdGhuYW1lKCkpCisJCisJZGVmIGRvbWVudV9uZXcoc2VsZiwgKmFyZ3MpOgorCQlXLlNldEN1cnNvcignd2F0Y2gnKQorCQlpbXBvcnQgUHlFZGl0CisJCXJldHVybiBQeUVkaXQuRWRpdG9yKCkKKwkKKwlkZWYgbWFrZXNjcmlwdHNtZW51KHNlbGYpOgorCQlXLlNldEN1cnNvcignd2F0Y2gnKQorCQlpZiBzZWxmLl9zY3JpcHRzOgorCQkJZm9yIGlkLCBpdGVtIGluIHNlbGYuX3NjcmlwdHMua2V5cygpOgorCQkJCWlmIHNlbGYubWVudWJhci5tZW51cy5oYXNfa2V5KGlkKToKKwkJCQkJbSA9IHNlbGYubWVudWJhci5tZW51c1tpZF0KKwkJCQkJbS5kZWxldGUoKQorCQkJc2VsZi5fc2NyaXB0cyA9IHt9CisJCWlmIHNlbGYuc2NyaXB0c21lbnU6CisJCQlpZiBoYXNhdHRyKHNlbGYuc2NyaXB0c21lbnUsICdpZCcpIGFuZCBzZWxmLm1lbnViYXIubWVudXMuaGFzX2tleShzZWxmLnNjcmlwdHNtZW51LmlkKToKKwkJCQlzZWxmLnNjcmlwdHNtZW51LmRlbGV0ZSgpCisJCXNlbGYuc2NyaXB0c21lbnUgPSBGcmFtZVdvcmsuTWVudShzZWxmLm1lbnViYXIsICJTY3JpcHRzIikKKwkJI0ZyYW1lV29yay5NZW51SXRlbShzZWxmLnNjcmlwdHNtZW51LCAiTmV3IHNjcmlwdCIsIE5vbmUsIHNlbGYuZG9tZW51X25ldykKKwkJI3NlbGYuc2NyaXB0c21lbnUuYWRkc2VwYXJhdG9yKCkKKwkJZnNzLCBmc3NfY2hhbmdlZCA9IHNlbGYuc2NyaXB0c2ZvbGRlci5SZXNvbHZlKCkKKwkJc2VsZi5zY3JpcHRzd2Fsayhmc3MuYXNfcGF0aG5hbWUoKSwgc2VsZi5zY3JpcHRzbWVudSkKKwkKKwlkZWYgbWFrZW9wZW53aW5kb3dzbWVudShzZWxmKToKKwkJZm9yIGkgaW4gcmFuZ2UobGVuKHNlbGYub3BlbndpbmRvd3NtZW51Lml0ZW1zKSk6CisJCQlzZWxmLm9wZW53aW5kb3dzbWVudS5tZW51LkRlbGV0ZU1lbnVJdGVtKDEpCisJCQlzZWxmLm9wZW53aW5kb3dzbWVudS5pdGVtcyA9IFtdCisJCXdpbmRvd3MgPSBbXQorCQlzZWxmLl9vcGVud2luZG93cyA9IHt9CisJCWZvciB3aW5kb3cgaW4gc2VsZi5fd2luZG93cy5rZXlzKCk6CisJCQl0aXRsZSA9IHdpbmRvdy5HZXRXVGl0bGUoKQorCQkJaWYgbm90IHRpdGxlOgorCQkJCXRpdGxlID0gIjxubyB0aXRsZT4iCisJCQl3aW5kb3dzLmFwcGVuZCh0aXRsZSwgd2luZG93KQorCQl3aW5kb3dzLnNvcnQoKQorCQlmb3IgdGl0bGUsIHdpbmRvdyBpbiB3aW5kb3dzOgorCQkJaXRlbSA9IEZyYW1lV29yay5NZW51SXRlbShzZWxmLm9wZW53aW5kb3dzbWVudSwgdGl0bGUsIGNhbGxiYWNrID0gc2VsZi5kb21lbnVfb3BlbndpbmRvd3MpCisJCQlzZWxmLl9vcGVud2luZG93c1tpdGVtLml0ZW1dID0gd2luZG93CisJCXNlbGYuX29wZW53aW5kb3dzY2hlY2ttYXJrID0gMAorCQlzZWxmLmNoZWNrb3BlbndpbmRvd3NtZW51KCkKKwkJCisJZGVmIGRvbWVudV9vcGVud2luZG93cyhzZWxmLCBpZCwgaXRlbSwgd2luZG93LCBldmVudCk6CisJCXcgPSBzZWxmLl9vcGVud2luZG93c1tpdGVtXQorCQl3LlNob3dXaW5kb3coKQorCQl3LlNlbGVjdFdpbmRvdygpCisJCisJZGVmIGRvbWVudV9xdWl0KHNlbGYpOgorCQlzZWxmLl9xdWl0KCkKKwkKKwlkZWYgZG9tZW51X3NhdmUoc2VsZiwgKmFyZ3MpOgorCQlwcmludCAiU2F2ZSIKKwkKKwlkZWYgX3F1aXQoc2VsZik6CisJCWltcG9ydCBQeUNvbnNvbGUsIFB5RWRpdAorCQlQeUNvbnNvbGUuY29uc29sZS53cml0ZXByZWZzKCkKKwkJUHlFZGl0LnNlYXJjaGVuZ2luZS53cml0ZXByZWZzKCkKKwkJZm9yIHdpbmRvdyBpbiBzZWxmLl93aW5kb3dzLnZhbHVlcygpOgorCQkJaWYgd2luZG93LmNsb3NlKCkgPiAwOgorCQkJCXJldHVybgorCQlzZWxmLnF1aXR0aW5nID0gMQorCitQeXRob25JREUoKQpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9SZXNvdXJjZXMvV2lkZ2V0cy5yc3JjLmhxeCBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvUmVzb3VyY2VzL1dpZGdldHMucnNyYy5ocXgKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYmViNTZlNgotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvUmVzb3VyY2VzL1dpZGdldHMucnNyYy5ocXgKQEAgLTAsMCArMSw4OSBAQAorKFRoaXMgZmlsZSBtdXN0IGJlIGNvbnZlcnRlZCB3aXRoIEJpbkhleCA0LjApCisKKzokJkdUQydHUEcoLVpGUjBiQmAiYkZoKk04UDAmNCElIU4hRjVIY1EqISohJSEzISEhIiUzISEhMyUhISEhQFgKKyohISEhRSdQWkNAQ1RDQGFORmBOISEhIjZCaCpbRSdhTEJBKmMiYCEhISFhQURANFJDQTRjLFIqY0ZRMGJFZmEKK2MpJiJiQ0BDYzEnWEotTGlpQk1HaSEhImJGaCpNOFAwJjQhJSFyaiElISohNVg2IlAjISMzIksqbEVoS2MjISEKKyEhJ1BaQ1FwZENBS2RGYEIhISEiI0dBNGRFZmpjIWAhISEoKmVFUi0qISEhIUZSOVpCUjlkRydwWkZgYCEhISIKK2JHQGpjQ0BhUEJoNFRFZmpjJCEhISEoKmVFUjBQRScqZUcoNFtFUi0lISEhIUJRUFpDKC0lISEhIUYoOWNEKC0KKzAhISEhRUA5Wkc5cFJFaDRbRSdQWkNBLSohISEhRmZLVENSNFhDMyEhIS0zIWEhIzMiM1ghI2AhNCFbbS0hMnIKK3EhISEhNSEhISElSiFOIUYsISFYIU4hOCIhIVMhTiE4LCEhWCFOISMhIiEjMyIzWCEjYCMzIzhKISEhIikhKiEKKyYhSiEiISEpIU4hZShJUDMhISEhIyEhJHJOIUIhIUNiMyIycnIhISkhTiFYLCEhWCFOITgsISFYISEhIyEhISEKKyFTISEhISpKISEhIychISEhTkIhISEpNEohISM0SiEhIUtKISEhKkohISEjSiEhISFKISEhITJtISEhJCUhLTMKKyFOITgsISFYISUzLHIkISRyckohISElSiEhISIpISohKCNgISwhKiEmITMhKyEqISYjYCEsISohIUohMyFOITgKKywhIVghTiFQKSEhISE1ISMzIjMpISEzISMhKiEwNGhxJCEhISEhSiEhcmohJyEhJ0ZOITZycmAhIyEqISwjYCEKKywhKiEmI2AhLCEqITFVVVVTISM0JUIhISolQiEhIU5CISEhI0IhISEhKSEjMyNybSEhISIsISVYIU4hOCwhIVgKKzQhMyUhI0ojMyIzWCEjaiEhISEpIU4hOCwhIVghTiE4LCEhWCFOITgsISFYISEhSiEkISExISFtISRpITJgIXEKKyEkYCExISFgISMhJHIhISEhNWAiLCEqISYjYCEsJTMlIiEhUyFOITgsISFaMyEhISMhKiEmI2AhLCEqISYjYCEKKywhKiEmI2AhLCEqISlycSJyYCRxIShgITEhITMhTiFBciEhISE1MyIqISohJiNKISslMyUiISFTIU4hOCshIVUKKzMhISEjISohJiNKISshKiEmI0ohKyEqISYjSiErISEhMyEiSiEoISFIISJtIShgIUghImAhJyEhMyEybSEhISIKKyohJU4hTiE4KyEhUzQhMyUhI0ojMyIzUyEjVCEhISEpIU4hOCshIVMhTiE4KyEhUyFOITgrISFTIU4hTXJgKHEKKyEyYCFIISFgIU4hQXIhISEjYlEhMSEhIi00JTknISkhIU4hQyJxW3JaNlImMUZAISEhISoxOUohISxgWFFFSiEKKyktI2khJ1FGMURlakEzJ0c1RFBLNTMnU1hCIVNbI2RrayEnKkJNZiIpLGBYcixKIS0yYmkhJExtWiEiIVssSiEKKzgoYmkhJyVrayEmVDJsYCE1QiNKWyNjbVohIWByLEohMSxiaSElI21aISIzSSxKIUI2VlMiZCVyWyEiKkojI20KKyw2VlMjLCZMMipQcDFBTCJJNnFtISYlbDNLJ2VLREBpISEhIjE5SiEhNlBqMUdCVDBIOGElNDhDKkVRUGQhISEKKyE2UEVyW05NUihjIXEsSiE1KlFpISNMNFohIkMjRVtyLUkhIiNFW3IrNSdscnIrS2QpJilbKyEhKVUoMCNUa00KK0IrS21bIkRLayxgWlNIZEtacnFVU1ErTEgsYFpTU2RLWnJwRFMwNUpacnBDYCUxI04pI2xyZlIpM2lVIVkzMnIKKzEpTGxyaFIzM2orJVkzSXI1ZCk2M0o1ZSFybUJKNVUhVDVRaSEmJ0YhISxKZiJmITUpJilKRCEiMykmIS0tISEKKzAtISJSJCYqJC0jaSEmMCIoWCUwWmokISROISIoMjgkcmMkYFohIjZGNGphJDhkQ2IhRyokMjgocmJSMyVlJ1gKKyEhTW0jMCIyODQkbSNVKi1KOEwiUyEmIVslJG0oMmJscmMrTCY1TkNbKighJWQnWCEhTW0hLSIyMzQwIlpybUoKK3IhK0w2KSYpSkQhIjMsYSFyLFtyKzJgRFNLOEtacmxqKUhKIm1VJ0MpRVtxcVUqZHIrYCEjLSNscmIwIiFkJjAKKzUzJG0hVSotcitgISctI2xyYjAiIWQmMDUzJG0hVSolSjVVIVU1TGkhIydGRCxgU3IsSiE4MmBGWyxKITEsYFgKK0ksSiEpNlZTITNOclshIilbLFtybVUoLVsiREtqLGBAU2Y4S1pycVVTUThjSSQySzFBTmplTE5lajYlNCY0TjQKK2JCQUYhISIpMy1DITMhJWpAcnFTWyNkS1pycmJTRyMiWiEiQko4I21TISFMU0ZkK1JVMEpRQWJtLFUoU1ssSiEKKytVKFkpRVtyVVUqTFNSTW1tISQrU1IjbVohIVVTU0xtWnJyYlNGYm0sVShOWyNrTUM1J2xya1VMQypQcDFBTmoKK2VNZGVqNiU0JjROS1RDZktYREBHU0chISE2UEIhISVqSDZSQCw2QVAtNCU5JzNmYVtGZjghTiE5JSFCIURGI0MKKykqTlM1NjQqKkQhUUIhQkojMyEpSiFMISUlITMpIyEzKSIhSiJKIltgMnJKcnFLcnIocnBbcmohJXJScnEycmkKK3JyInJtJHJKKHEhSWkhIU4hIyEhISElMyFOITMwSiIqYCVOYDU1TEorKyEqKSFOISMpISlKIiIhJSMhSiUjITMKKykhKiElJEIhSW0icm0ocmlyck1ycUlyanJyTXJxMnJgSXIhcmkickoocSEhKiEhSiEhISIlISEhIkohJyEhQiEKKyJKIicpLUJhcnJNJy0lQkoiSiEnISFCISJKISMzIiEyISFtISRgITIhJ3BKbGgocnFycnByck1bRidwSiRgITIKKyEhbSEkYCEhISEhRiEiYCEhITIpIU4hNSEiISMzIjQhISUhIzMjOEohISEiKSEqISYhSiEiISEpIU4iJSMhKiEKKyYlISEzISohJiFKIzMiNCEhJSEjMyMhKSEhYCEkSiEyISFxISRtITJKIW0hJEohLSEhSiMzI2ApISFgISNKISoKKyEhTCEjJSEpSiFOISNKIS0hIUojMyRKKSEhMnEzIkohIlFDISVycm0hIWAjMyRgYCEhISEyISEhISRGISEhIWEKK2AhISEwKCEhISQlRiEhIWRGISEhLUYhISEkRiEhISFtISEhIS0hKiE0bUojMyIpISUhKiEmJSEhMyEqISo1ISEKKyEhJUohTiE4IyEhJSEhSiMzJTMpIU4hODMhIiEhTiE4IyEqISYlISEzISohMTJySkltIXJKIm0hJEohJSFOIjgKK3JxIiEzIyMhJTMhKyEhMyMzJUopISEycTMiSiEiUUMhJXJybSEhYCMzJ0pycnJtISQ0JUYhITAlRiEhIWRGISEKKyEkRiEhISEtIU4iUishKiElSiEpIU4hODMhIiEhTiFQKSEhISE1ISMzIjMlISEzISIhKiE0IUojMyI0ISElISMKKzMiMykhTiE4MyEiISFOIUojISEtISFpISRgITJKIXIhJGkhMiEhaSEkISEpIU4hWCMhIS0hIWkhJGAhMkohciEKKyRpITIhIWkhJCEhKSFOIWkiISEkck4hQiEhMyMzI0opISFgISRKITIhIXEhJG0hMkohbSEkSiEtISFKIzMjWFMKKyFOITUhIUojMyI0ISElISMzIzhKISEhIikhKiEmITMhIiEhJSFOIiUjISohJiUhITMhKiEmIUojMyI0ISElISMKKzMkTXJpKHIhMmkhSSEhaSEiISohOTJySkltIXJKIm0hJEohJSFOIikiISEkck4hQiEhMyMzJSRyaShyITJpIUkKKyEhaSEiISohMCJGakojSiEhNiU0JjRKKEEhISIxcUo5JzZSOTE5W3InNTFGSS0jNFohIUprLEohLTEjaSEkTEMKK1ohIiEtNCEhIkUhSyM4aCEiQiEhIkwlS1pycmJTRyMiWnJyYEArISInOThtWyNOKlIyYEBTS00hSTIhIis0UUYKKyVbJTRaIyREJkYhIkohISZGRiEhMyFgIiEhIyFyIStMKTk4bVsjTipSMmBAU0tNIUkyISNtNCdpKTBTOWAhQCEKKyEhNkItNEohIkUhSyM4aCEiQiEhIiskZSdybUMpRVtyJzUnbHJhTW1tKSFrVGtkS1pybUMpRVtyJzJjYDMlK1IKK1YyODZyZCVLWnJwIilFW3IzMmNgSiRVUlY1J2xyZCVLWnJwIXIyIiEzVUhYcDRJckQ1J2xyZk5LWnJwU3IyIyEKKzFVSFkpRVtyRDUnbHJmTW1tJSIjVGtkS1pycFQpRVtyTjJjYDMkVVJWNSdscmQlS1pycTNyMiIhJVVIWSlFW3IKKyc1J2xyaiRtbSUhRFRrZEtacnE0KUVbcloyY2AzJStSVjUnbHJsTktacnIpcjIiITFVSFkpRVtyYjJjYCEmVVIKK1Y1J2xybU5LWnJyKXIyI0ozVUhYZixbcmQ5OHAicUoiZjUmI1NNJCFJMkoiKzNmaSVHSiJKNVA5MixgVCNDY20KKyRVKUJgKHAiKDIhIjk2Ym0rM1FGYCFlKiEyYCNTS00hSWQlRmshLGElRUpiaTRAaSlaJTlRJ1AqJEIiRG00J20KKyM4ZDArM2ZpJUdKIkojLFQlRSwqNTNmI1owUzBgIThjSSQySzFBTmplTGg0YkdAak1GaDRiREBqUiEhKSJiOGoKK0BycmopamFgYCpRaSEjJEJaISFgTkVKITExI1MhIlRLVSEhKUpFSiE4KSYhSkQhISknTEohNE0hVSEhKjgzJG0KKyEtIiwzRUohNTJgI1NOZEtacnJpYCImRyEyYCFyIWJtLDZWVnBtJVMhNnFtISQnRkosYFkjQ2NtWnJya1NLRUMKK1pycmpbIk1tbXJtUVNKaCEhJSE4ciErTClCIUpbI2QqUjJgMVNLOGNJJCRLMUFOamVNJTRiQkFHOENBS2QzZjkKK1hFISEhISVqQHJrailqYW1gKlFpISQkSlohIkJVLEohQjUnbHJhVUtkKSU4SjgjbVMhIUxTRmVQMlUwSkpBYmUKKylycWlbLFtyWlUoU1sja0tsNSdsclkrTEJVKmorLEohKUNKISMoTG0sVSswKUVbckRVJDhKLFtyREZLJExTI2UKKyFycilRLFtySGlVLVgsW3JMaVVCWiEwayRoU0ItNCEhJ0UzISJFTCImKSYhWUQhIjNycDNKRVtyOFMjTk5FW3IKKzgqJiw4bEohODI5LHJkTWVVISEsclhNZVUhITZyZiZiK0E4M1k1W3FaMiEzWiNOKlpyckMrRVtyNUNlVEM2Y20KK1pycCtVKEwiSSpKSytKZkcrKSUtSjgjZVMhIUVycSNlUyEhVnJyJUtacnJKcitgISMyYTFTVSVLWnJySyNDYyEKK1pycmIzISdscnEjIiYpJiFiKyEhM05OIWAhSCIpbE5NMzNIKiEyYCNTVSVLWnJySlsha1NJR0oiSihKYGIhIU4KK2AhJ0I4MiEwNTNiIitkLS1aIyQhJU4hIiQyOCRycFEhJzhOMWY0J2hINU5DWSEhI0opJThKOCghM2QnSiEhWSIKK1pybCloMyEhIyklOEo4JCFTISEsM0VbckIwZCEhIkwiJikmIWArYCEnWCdKISJRbSspJThKOCRHUyEhQiEiTSEKK1YhIStgRGAhJ0UiQlsiNm1acnIzWyNjbScsYmxyVk5ra3JHSzJsYCEzKSU4SjgkIVMhISwzRVtyQjBkISEhTCIKKyYpJiFoRCEhJyEhQmArYCEjWCdYISJRYEAsYDhyLFtyZCxgWHIsW3JmLGBHMVpbZkg2cW0hJSMiJikmIWhEISEKKychIUJKRVtyOFMjVEooTlQlQ2FTWyI2bVpycjNbI2NtbSEhMCJxSiQrNSYiMVpbZVo2cW0hJSNlNnJySllEYCEKKyVycmBKNDUiMy0jSiEhWSJacnBLNjMkZSFyclQ1MyRlIXJyaUo0NSIzIyNKISEhITRDYEopLEohIXJyUFIkTksKK1pybVQicUojJzUmI1NDUSEtNSdscmJOKGshKVQpOCtLUTUnbHJiVUxHM1FIU1IlS1pyckxTU1VMSDVMaSEjUUIKKyc1TGkhIydGTCklOEo4KCEzZCdKISFNRyEhISlKNDUiMzBmSiEiSiEnMmNgIS1VTEYsYFpTU0xtWnJtRFNGYm0KK1pycWtTSDVtWnJxa1NmOEtacmw1U1E4Y0kkMksxQU5qZUxOZWo2JTQmNE40YkJBRiEhI0pyMmNtISUnQ1EtJCIKK1FDTSFgQ1FCYC0nQ1EtJCEhJSQhYENRQmAtJ0NRLSQiUUNNIWBDUUIhNlBCISElTVIoJCFELEohQipRaSEmJEoKK1ohIWlmLEohLSonaSEjJCFaISJUUjNQMCFDYFQ2MydGSjhkIlIwUSFkLGBTciFjbSUsYmkhJSNtLChgOSMqZGsKK2tyMEMybGAhOEIiU1sjTW0kMmAzWyxKITMsYFhJIjRtbSEhJjFaW2JrNnFtISYlY0kkJEsxQUwiSTZxbSEmJWwKKzNLJ2VLREBpIU4hQyUhISEiISExISJtISIhISUhITMicnIocm0hMyEiISElISJtISRKISUhISEhIiEhMSEibSEKKzJpIXJKIWkkcnJbcnFycmxyckoxISRxITJpIUkhIWkhIiEhISghIUYhISElISEhITQlISEhJSIhISEhJlYiY0cKKywkI1JIISEhISghJHEhITAzNTgwOCEhOCEpTmElNDhCISEzIlUzZTk1OGAhJCEpKk1EQDBaISEtIVhKKDghIWAKKyFOIUoiZTMhQiEhISFiISMzIiEoQCEjKSEhISczISEjMyIhKEEhJC0hISEoSSEqISUhR0ohM0ohISFMaSFOITMKKyJmMyIwISEhI0hgIzMiISg4ISEhSiEhLCkhKiElIUdGIUIzISEjSUIhTiEzImUhIkEpISEmUEojMyIhKDkhJmAKK0ohIUFIISohJSFHRXJyYCEhIkxCIU4hMyJlcnJyISEhMmIhIzMiISg4cnJtISEhQ1ohKiElIUdBcnJgISEiZjMKKyFOITMiZVtyciEhISlASiMzIiEoQXJybSEhIU5TISohJSNlNGhFZGFURVE5LTQlOScjZjBYRWgwUEMnJmJGUXAKK2gjQHBgQ0BqS0ZSKltHYSJNRSdwY0NANEtGUipbR2gwW0UnUE4kUXBgQ0BqS0ZSKltHaDBbRSdQTiNRJmJGUXAKK2hGUVBSRCgzKkJBKmJFaEdORWhHWiIlS0tFUTMlNFFQY0chWSNGUXBoRmY5YjYlNCY0VjRJOgpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9TcGxhc2gucHkgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1NwbGFzaC5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45OWEzNmZhCi0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9TcGxhc2gucHkKQEAgLTAsMCArMSwxNjIgQEAKK2ltcG9ydCBEbGcKK2ltcG9ydCBSZXMKKworc3BsYXNoID0gRGxnLkdldE5ld0RpYWxvZyg0NjgsIC0xKQorc3BsYXNoLkRyYXdEaWFsb2coKQorCitpbXBvcnQgUWQsIFRFLCBGbSwgc3lzCisKK19yZWFsX19pbXBvcnRfXyA9IE5vbmUKKworZGVmIGluc3RhbGxfaW1wb3J0aG9vaygpOgorCWdsb2JhbCBfcmVhbF9faW1wb3J0X18KKwlpbXBvcnQgX19idWlsdGluX18KKwlpZiBfcmVhbF9faW1wb3J0X18gaXMgTm9uZToKKwkJX3JlYWxfX2ltcG9ydF9fID0gX19idWlsdGluX18uX19pbXBvcnRfXworCQlfX2J1aWx0aW5fXy5fX2ltcG9ydF9fID0gbXlfX2ltcG9ydF9fCisKK2RlZiB1bmluc3RhbGxfaW1wb3J0aG9vaygpOgorCWdsb2JhbCBfcmVhbF9faW1wb3J0X18KKwlpZiBfcmVhbF9faW1wb3J0X18gaXMgbm90IE5vbmU6CisJCWltcG9ydCBfX2J1aWx0aW5fXworCQlfX2J1aWx0aW5fXy5fX2ltcG9ydF9fID0gX3JlYWxfX2ltcG9ydF9fCisJCV9yZWFsX19pbXBvcnRfXyA9IE5vbmUKKworX3Byb2dyZXNzID0gMAorCitkZWYgaW1wb3J0aW5nKG1vZHVsZSk6CisJZ2xvYmFsIF9wcm9ncmVzcworCVFkLlNldFBvcnQoc3BsYXNoKQorCWZvbnRJRCA9IEZtLkdldEZOdW0oIlB5dGhvbi1TYW5zIikKKwlpZiBub3QgZm9udElEOgorCQlmb250SUQgPSBnZW5ldmEKKwlRZC5UZXh0Rm9udChmb250SUQpCisJUWQuVGV4dFNpemUoOSkKKwlyZWN0ID0gKDM1LCAyNjAsIDM2NSwgMjc2KQorCWlmIG1vZHVsZToKKwkJVEUuVEVUZXh0Qm94KCdJbXBvcnRpbmc6ICcgKyBtb2R1bGUsIHJlY3QsIDApCisJCWlmIG5vdCBfcHJvZ3Jlc3M6CisJCQlRZC5GcmFtZVJlY3QoKDM1LCAyNzYsIDM2NSwgMjg0KSkKKwkJcG9zID0gbWluKDM2ICsgMzMwICogX3Byb2dyZXNzIC8gNDQsIDM2NCkKKwkJUWQuUGFpbnRSZWN0KCgzNiwgMjc3LCBwb3MsIDI4MykpCisJCV9wcm9ncmVzcyA9IF9wcm9ncmVzcyArIDEKKwllbHNlOgorCQlRZC5FcmFzZVJlY3QocmVjdCkKKwkJUWQuUGFpbnRSZWN0KCgzNiwgMjc3LCBwb3MsIDI4MykpCisKK2RlZiBteV9faW1wb3J0X18obmFtZSwgZ2xvYmFscz1Ob25lLCBsb2NhbHM9Tm9uZSwgZnJvbWxpc3Q9Tm9uZSk6CisJdHJ5OgorCQlyZXR1cm4gc3lzLm1vZHVsZXNbbmFtZV0KKwlleGNlcHQgS2V5RXJyb3I6CisJCXRyeToKKwkJCWltcG9ydGluZyhuYW1lKQorCQlleGNlcHQ6CisJCQl0cnk6CisJCQkJcnYgPSBfcmVhbF9faW1wb3J0X18obmFtZSkKKwkJCWZpbmFsbHk6CisJCQkJdW5pbnN0YWxsX2ltcG9ydGhvb2soKQorCQkJcmV0dXJuIHJ2CisJCXJldHVybiBfcmVhbF9faW1wb3J0X18obmFtZSkKKworaW5zdGFsbF9pbXBvcnRob29rKCkKKwora0hpZ2hMZXZlbEV2ZW50ID0gMjMKK2ltcG9ydCBXaW4KK2Zyb20gRm9udHMgaW1wb3J0ICoKK2Zyb20gUXVpY2tEcmF3IGltcG9ydCAqCitmcm9tIFRleHRFZGl0IGltcG9ydCAqCitpbXBvcnQgc3RyaW5nCitpbXBvcnQgc3lzCitpbXBvcnQgcmFuZG9tCisKK19rZWVwc3BsYXNoc2NyZWVub3BlbiA9IDAKKworYWJvdXR0ZXh0MSA9ICIiIlRoZSBQeXRob24gSW50ZWdyYXRlZCBEZXZlbG9wZW1lbnQgRW52aXJvbm1lbnQgZm9yIHRoZSBNYWNpbnRvc2iBCitWZXJzaW9uOiAlcworQ29weXJpZ2h0IDE5OTcgSnVzdCB2YW4gUm9zc3VtLCBMZXR0ZXJyb3IuIDxqdXN0QGtub3dhcmUubmw+CisKK1B5dGhvbiAlcworJXMKK1dyaXR0ZW4gYnkgR3VpZG8gdmFuIFJvc3N1bSB3aXRoIEphY2sgSmFuc2VuIChhbmQgb3RoZXJzKQorCitTZWU6IDxodHRwOi8vd3d3LnB5dGhvbi5vcmcvPiBmb3IgaW5mb3JtYXRpb24gYW5kIGRvY3VtZW50YXRpb24uIiIiCisKK2ZsYXV3ZWt1bCA9IFsJJ0dvb2RkYXksIEJydWNlLicsIAorCQkJJ1doYXS5cyBuZXc/JywgCisJCQknTnVkZ2UsIG51ZGdlLCBzYXkgbm8gbW9yZSEnLCAKKwkJCSdObywgbm8gc2lyLCBpdLlzIG5vdCBkZWFkLiBJdLlzIHJlc3RpbmcuJywKKwkJCSdBbGJhdHJvcyEnLAorCQkJJ0l0uXMgLiAuIC4nLAorCQkJJ0lzIHlvdXIgbmFtZSBub3QgQnJ1Y2UsIHRoZW4/JywKKwkJCSIiIkJ1dCBNciBGLkcuIFN1cGVybWFuIGhhcyBhIHNlY3JldCBpZGVudGl0eSAuIC4gLiAKK3doZW4gdHJvdWJsZSBzdHJpa2VzIGF0IGFueSB0aW1lIC4gLiAuIAorYXQgYW55IHBsYWNlIC4gLiAuIGhlIGlzIHJlYWR5IHRvIGJlY29tZSAuIC4gLiAKK0JpY3ljbGUgUmVwYWlyIE1hbiEiIiIKKwkJCV0KKworZGVmIG5sMnJldHVybih0ZXh0KToKKwlyZXR1cm4gc3RyaW5nLmpvaW4oc3RyaW5nLnNwbGl0KHRleHQsICdcbicpLCAnXHInKQorCitkZWYgVXBkYXRlU3BsYXNoKGRyYXdkaWFsb2cgPSAwLCB3aGF0ID0gMCk6CisJaWYgZHJhd2RpYWxvZzoKKwkJc3BsYXNoLkRyYXdEaWFsb2coKQorCWRyYXd0ZXh0KHdoYXQpCisJV2luLlZhbGlkUmVjdChzcGxhc2guR2V0V2luZG93UG9ydCgpLnBvcnRSZWN0KQorCitkZWYgZHJhd3RleHQod2hhdCA9IDApOgorCVFkLlNldFBvcnQoc3BsYXNoKQorCWZvbnRJRCA9IEZtLkdldEZOdW0oIlB5dGhvbi1TYW5zIikKKwlpZiBub3QgZm9udElEOgorCQlmb250SUQgPSBnZW5ldmEKKwlRZC5UZXh0Rm9udChmb250SUQpCisJUWQuVGV4dFNpemUoOSkKKwlyZWN0ID0gKDEwLCAxMjUsIDM5MCwgMjYwKQorCWlmIG5vdCB3aGF0OgorCQlpbXBvcnQgX19tYWluX18KKwkJYWJvdXR0eHQgPSBubDJyZXR1cm4oYWJvdXR0ZXh0MSAgXAorCQkJJSAoX19tYWluX18uX192ZXJzaW9uX18sIHN5cy52ZXJzaW9uLCBzeXMuY29weXJpZ2h0KSkKKwllbHNlOgorCQlhYm91dHR4dCA9IG5sMnJldHVybihyYW5kb20uY2hvaWNlKGZsYXV3ZWt1bCkpCisJVEUuVEVUZXh0Qm94KGFib3V0dHh0LCByZWN0LCB0ZUp1c3RDZW50ZXIpCisKK1VwZGF0ZVNwbGFzaCgxKQorCitkZWYgd2FpdCgpOgorCWltcG9ydCBFdnQKKwlmcm9tIEV2ZW50cyBpbXBvcnQgKgorCWdsb2JhbCBzcGxhc2gKKwl0cnk6CisJCXNwbGFzaAorCWV4Y2VwdCBOYW1lRXJyb3I6CisJCXJldHVybgorCVFkLkluaXRDdXJzb3IoKQorCXRpbWUgPSBFdnQuVGlja0NvdW50KCkKKwl3aGF0dGV4dCA9IDAKKwl3aGlsZSBfa2VlcHNwbGFzaHNjcmVlbm9wZW46CisJCW9rLCBldmVudCA9IEV2dC5FdmVudEF2YWlsKGhpZ2hMZXZlbEV2ZW50TWFzaykKKwkJaWYgb2s6CisJCQkjIGdvdCBhcHBsZSBldmVudCwgYmFjayB0byBtYWlubG9vcAorCQkJYnJlYWsKKwkJb2ssIGV2ZW50ID0gRXZ0LkV2ZW50QXZhaWwobURvd25NYXNrIHwga2V5RG93bk1hc2sgfCB1cGRhdGVNYXNrKQorCQlpZiBvazoKKwkJCW9rLCBldmVudCA9IEV2dC5XYWl0TmV4dEV2ZW50KG1Eb3duTWFzayB8IGtleURvd25NYXNrIHwgdXBkYXRlTWFzaywgMzApCisJCQlpZiBvazoKKwkJCQkod2hhdCwgbWVzc2FnZSwgd2hlbiwgd2hlcmUsIG1vZGlmaWVycykgPSBldmVudAorCQkJCWlmIHdoYXQgPT0gdXBkYXRlRXZ0OgorCQkJCQlpZiBXaW4uV2hpY2hXaW5kb3cobWVzc2FnZSkgPT0gc3BsYXNoOgorCQkJCQkJVXBkYXRlU3BsYXNoKDEsIHdoYXR0ZXh0KQorCQkJCWVsc2U6CisJCQkJCWJyZWFrCisJCWlmIEV2dC5UaWNrQ291bnQoKSAtIHRpbWUgPiAzNjA6CisJCQl3aGF0dGV4dCA9IG5vdCB3aGF0dGV4dAorCQkJZHJhd3RleHQod2hhdHRleHQpCisJCQl0aW1lID0gRXZ0LlRpY2tDb3VudCgpCisJZGVsIHNwbGFzaAorCSNSZXMuQ2xvc2VSZXNGaWxlKHNwbGFzaHJlc2ZpbGUpCisKK2RlZiBhYm91dCgpOgorCWdsb2JhbCBzcGxhc2gsIHNwbGFzaHJlc2ZpbGUsIF9rZWVwc3BsYXNoc2NyZWVub3BlbgorCV9rZWVwc3BsYXNoc2NyZWVub3BlbiA9IDEKKwlzcGxhc2ggPSBEbGcuR2V0TmV3RGlhbG9nKDQ2OCwgLTEpCisJc3BsYXNoLkRyYXdEaWFsb2coKQorCXdhaXQoKQpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL0ZvbnRTZXR0aW5ncy5weSBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9Gb250U2V0dGluZ3MucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMGEzMzFkZgotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9Gb250U2V0dGluZ3MucHkKQEAgLTAsMCArMSwxMzkgQEAKKyIiInVzYWdlOiAKK25ld3NldHRpbmdzID0gcHJpbnQgRm9udERpYWxvZygoJ0NoaWNhZ28nLCAwLCAxMiwgKDAsIDAsIDApKSkJIyBmb250IG5hbWUgb3IgaWQsIHN0eWxlIGZsYWdzLCBzaXplLCBjb2xvciAoY29sb3IgaXMgaWdub3JlZCkKK2lmIG5ld3NldHRpbmdzOgorCWZvbnQsIHN0eWxlLCBzaXplLCBjb2xvciA9IG5ld3NldHRpbmdzCSMgJ2ZvbnQnIGlzIGFsd2F5cyB0aGUgZm9udCBuYW1lLCBub3QgdGhlIGlkIG51bWJlcgorCSMgZG8gc29tZXRoaW5nCisiIiIKKworaW1wb3J0IFcKK2ltcG9ydCBQeUVkaXQKK2ltcG9ydCBUZXh0RWRpdAoraW1wb3J0IHN0cmluZworaW1wb3J0IHR5cGVzCisKK19zdHlsZW5hbWVzID0gWyJQbGFpbiIsICJCb2xkIiwgIkl0YWxpYyIsICJVbmRlcmxpbmUiLCAiT3V0bGluZSIsICJTaGFkb3ciLCAiQ29uZGVuc2VkIiwgIkV4dGVuZGVkIl0KKworCitjbGFzcyBfRm9udERpYWxvZzoKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgZm9udHNldHRpbmdzKToKKwkJbGVmdG1hcmdpbiA9IDQ2CisJCXNlbGYudyA9IFcuTW9kYWxEaWFsb2coKDQ0MCwgMTgwKSwgJ0ZvbnQgc2V0dGluZ3MnKQorCQlzZWxmLncuZm9udHRpdGxlID0gVy5UZXh0Qm94KCgxMCwgMTIsIDMwLCAxNCksICJGb250OiIsIFRleHRFZGl0LnRlSnVzdFJpZ2h0KQorCQlzZWxmLncucG9wID0gVy5Gb250TWVudSgobGVmdG1hcmdpbiwgMTAsIDE2LCAxNiksIHNlbGYuc2V0Zm9udCkKKwkJc2VsZi53LmZvbnRuYW1lID0gVy5UZXh0Qm94KChsZWZ0bWFyZ2luICsgMjAsIDEyLCAxNTAsIDE0KSkKKwkJc2VsZi53LnNpemV0aXRsZSA9IFcuVGV4dEJveCgoMTAsIDM4LCAzMCwgMTQpLCAiU2l6ZToiLCBUZXh0RWRpdC50ZUp1c3RSaWdodCkKKwkJc2VsZi53LnNpemVlZGl0ID0gVy5FZGl0VGV4dCgobGVmdG1hcmdpbiwgMzUsIDQwLCAyMCksICIiLCBzZWxmLmNoZWNrc2l6ZSkKKwkJc3R5bGV0b3AgPSA2NAorCQlzZWxmLncuc3R5bGV0aXRsZSA9IFcuVGV4dEJveCgoMTAsIHN0eWxldG9wICsgMiwgMzAsIDE0KSwgIlN0eWxlOiIsIFRleHRFZGl0LnRlSnVzdFJpZ2h0KQorCQlmb3IgaSBpbiByYW5nZShsZW4oX3N0eWxlbmFtZXMpKToKKwkJCXRvcCA9IHN0eWxldG9wICsgKGkgJSA0KSAqIDIwCisJCQlsZWZ0ID0gbGVmdG1hcmdpbiArIDgwICogKGkgPiAzKSAtIDIKKwkJCWlmIGk6CisJCQkJc2VsZi53W2ldID0gVy5DaGVja0JveCgobGVmdCwgdG9wLCA3NiwgMTYpLCBfc3R5bGVuYW1lc1tpXSwgc2VsZi5kb3N0eWxlKQorCQkJZWxzZToKKwkJCQlzZWxmLndbaV0gPSBXLkNoZWNrQm94KChsZWZ0LCB0b3AsIDcwLCAxNiksIF9zdHlsZW5hbWVzW2ldLCBzZWxmLmRvcGxhaW4pCisJCXNlbGYudy5jYW5jZWxidXR0b24gPSBXLkJ1dHRvbigoLTE4MCwgLTI2LCA4MCwgMTYpLCAiQ2FuY2VsIiwgc2VsZi5jYW5jZWwpCisJCXNlbGYudy5kb25lYnV0dG9uID0gVy5CdXR0b24oKC05MCwgLTI2LCA4MCwgMTYpLCAiRG9uZSIsIHNlbGYuZG9uZSkKKwkJCisJCXNhbXBsZXRleHQgPSAiU2FtcGxlIHRleHQuIgorCQlzZWxmLncuc2FtcGxlID0gVy5FZGl0VGV4dCgoMjMwLCAxMCwgLTEwLCAxMzApLCBzYW1wbGV0ZXh0LCBmb250c2V0dGluZ3MgPSBmb250c2V0dGluZ3MpCisJCQorCQlzZWxmLncuc2V0ZGVmYXVsdGJ1dHRvbihzZWxmLncuZG9uZWJ1dHRvbikKKwkJc2VsZi53LmJpbmQoJ2NtZC4nLCBzZWxmLncuY2FuY2VsYnV0dG9uLnB1c2gpCisJCXNlbGYudy5iaW5kKCdjbWR3Jywgc2VsZi53LmRvbmVidXR0b24ucHVzaCkKKwkJc2VsZi5sYXN0c2l6ZSA9IGZvbnRzZXR0aW5nc1syXQorCQlzZWxmLl9ydiA9IE5vbmUKKwkJc2VsZi5zZXQoZm9udHNldHRpbmdzKQorCQlzZWxmLncub3BlbigpCisJCisJZGVmIHNldChzZWxmLCBmb250c2V0dGluZ3MpOgorCQlmb250LCBzdHlsZSwgc2l6ZSwgY29sb3IgPSBmb250c2V0dGluZ3MKKwkJaWYgdHlwZShmb250KSA8PiB0eXBlcy5TdHJpbmdUeXBlOgorCQkJaW1wb3J0IFJlcworCQkJcmVzID0gUmVzLkdldFJlc291cmNlKCdGT05EJywgZm9udCkKKwkJCWZvbnQgPSByZXMuR2V0UmVzSW5mbygpWzJdCisJCXNlbGYudy5mb250bmFtZS5zZXQoZm9udCkKKwkJc2VsZi53LnNpemVlZGl0LnNldChzdHIoc2l6ZSkpCisJCWlmIHN0eWxlOgorCQkJZm9yIGkgaW4gcmFuZ2UoMSwgbGVuKF9zdHlsZW5hbWVzKSk6CisJCQkJc2VsZi53W2ldLnNldChzdHlsZSAmIDB4MDEpCisJCQkJc3R5bGUgPSBzdHlsZSA+PiAxCisJCWVsc2U6CisJCQlzZWxmLndbMF0uc2V0KDEpCisJCisJZGVmIGdldChzZWxmKToKKwkJZm9udCA9IHNlbGYudy5mb250bmFtZS5nZXQoKQorCQlzdHlsZSA9IDAKKwkJaWYgbm90IHNlbGYud1swXS5nZXQoKToKKwkJCWZsYWcgPSAweDAxCisJCQlmb3IgaSBpbiByYW5nZSgxLCBsZW4oX3N0eWxlbmFtZXMpKToKKwkJCQlpZiBzZWxmLndbaV0uZ2V0KCk6CisJCQkJCXN0eWxlID0gc3R5bGUgfCBmbGFnCisJCQkJZmxhZyA9IGZsYWcgPDwgMQorCQlzaXplID0gc2VsZi5sYXN0c2l6ZQorCQlyZXR1cm4gKGZvbnQsIHN0eWxlLCBzaXplLCAoMCwgMCwgMCkpCisJCisJZGVmIGRvaXQoc2VsZik6CisJCWlmIHNlbGYud1swXS5nZXQoKToKKwkJCXN0eWxlID0gMAorCQllbHNlOgorCQkJc3R5bGUgPSAwCisJCQlmb3IgaSBpbiByYW5nZSgxLCBsZW4oX3N0eWxlbmFtZXMpKToKKwkJCQlpZiBzZWxmLndbaV0uZ2V0KCk6CisJCQkJCXN0eWxlID0gc3R5bGUgfCAyICoqIChpIC0gMSkKKwkJI3NlbGYudy5zYW1wbGUuc2V0KGBzdHlsZWApCisJCXNlbGYudy5zYW1wbGUuc2V0Zm9udHNldHRpbmdzKHNlbGYuZ2V0KCkpCisJCisJZGVmIGNoZWNrc2l6ZShzZWxmKToKKwkJc2l6ZSA9IHNlbGYudy5zaXplZWRpdC5nZXQoKQorCQlpZiBub3Qgc2l6ZToKKwkJCXJldHVybgorCQl0cnk6CisJCQlzaXplID0gc3RyaW5nLmF0b2koc2l6ZSkKKwkJZXhjZXB0IChWYWx1ZUVycm9yLCBPdmVyZmxvd0Vycm9yKToKKwkJCWdvb2QgPSAwCisJCWVsc2U6CisJCQlnb29kID0gMSA8PSBzaXplIDw9IDUwMAorCQlpZiBnb29kOgorCQkJaWYgc2VsZi5sYXN0c2l6ZSA8PiBzaXplOgorCQkJCXNlbGYubGFzdHNpemUgPSBzaXplCisJCQkJc2VsZi5kb2l0KCkKKwkJZWxzZToKKwkJCSMgYmVlcCEKKwkJCXNlbGYudy5zaXplZWRpdC5zZXQoYHNlbGYubGFzdHNpemVgKQorCQkJc2VsZi53LnNpemVlZGl0LnNlbGVjdGFsbCgpCisJCisJZGVmIGRvcGxhaW4oc2VsZik6CisJCWZvciBpIGluIHJhbmdlKDEsIGxlbihfc3R5bGVuYW1lcykpOgorCQkJc2VsZi53W2ldLnNldCgwKQorCQlzZWxmLndbMF0uc2V0KDEpCisJCXNlbGYuZG9pdCgpCisJCisJZGVmIGRvc3R5bGUoc2VsZik6CisJCWZvciBpIGluIHJhbmdlKDEsIGxlbihfc3R5bGVuYW1lcykpOgorCQkJaWYgc2VsZi53W2ldLmdldCgpOgorCQkJCXNlbGYud1swXS5zZXQoMCkKKwkJCQlicmVhaworCQllbHNlOgorCQkJc2VsZi53WzBdLnNldCgxKQorCQlzZWxmLmRvaXQoKQorCQorCWRlZiBjYW5jZWwoc2VsZik6CisJCXNlbGYudy5jbG9zZSgpCisJCisJZGVmIGRvbmUoc2VsZik6CisJCXNlbGYuX3J2ID0gc2VsZi5nZXQoKQorCQlzZWxmLncuY2xvc2UoKQorCQorCWRlZiBzZXRmb250KHNlbGYsIGZvbnRuYW1lKToKKwkJc2VsZi53LmZvbnRuYW1lLnNldChmb250bmFtZSkKKwkJc2VsZi5kb2l0KCkKKwkKKworZGVmIEZvbnREaWFsb2coZm9udHNldHRpbmdzKToKKwlmZCA9IF9Gb250RGlhbG9nKGZvbnRzZXR0aW5ncykKKwlyZXR1cm4gZmQuX3J2CisKK2RlZiB0ZXN0KCk6CisJcHJpbnQgRm9udERpYWxvZygoJ1phcGF0YS1MaWdodCcsIDAsIDI1LCAoMCwgMCwgMCkpKQpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL01hY1ByZWZzLnB5IGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL01hY1ByZWZzLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmNhZjcxYjgKLS0tIC9kZXYvbnVsbAorKysgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvTWFjUHJlZnMucHkKQEAgLTAsMCArMSwxMDkgQEAKK2ltcG9ydCBtYWNmcworaW1wb3J0IG1hcnNoYWwKK2ltcG9ydCBvcworaW1wb3J0IG1hY29zdG9vbHMKK2ltcG9ydCB0eXBlcworCitrT25TeXN0ZW1EaXNrID0gMHg4MDAwCisKKworY2xhc3MgUHJlZk9iamVjdDoKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgZGljdCA9IE5vbmUpOgorCQlpZiBkaWN0ID09IE5vbmU6CisJCQlzZWxmLl9wcmVmc2RpY3QgPSB7fQorCQllbHNlOgorCQkJc2VsZi5fcHJlZnNkaWN0ID0gZGljdAorCQorCWRlZiBfX2xlbl9fKHNlbGYpOgorCQlyZXR1cm4gbGVuKHNlbGYuX3ByZWZzZGljdCkKKwkKKwlkZWYgX19kZWxhdHRyX18oc2VsZiwgYXR0cik6CisJCWlmIHNlbGYuX3ByZWZzZGljdC5oYXNfa2V5KGF0dHIpOgorCQkJZGVsIHNlbGYuX3ByZWZzZGljdFthdHRyXQorCQllbHNlOgorCQkJcmFpc2UgQXR0cmlidXRlRXJyb3IsICdkZWxldGUgbm9uLWV4aXN0aW5nIGluc3RhbmNlIGF0dHJpYnV0ZScKKwkKKwlkZWYgX19nZXRhdHRyX18oc2VsZiwgYXR0cik6CisJCWlmIGF0dHIgPT0gJ19fbWVtYmVyc19fJzoKKwkJCWtleXMgPSBzZWxmLl9wcmVmc2RpY3Qua2V5cygpCisJCQlrZXlzLnNvcnQoKQorCQkJcmV0dXJuIGtleXMKKwkJdHJ5OgorCQkJcmV0dXJuIHNlbGYuX3ByZWZzZGljdFthdHRyXQorCQlleGNlcHQgS2V5RXJyb3I6CisJCQlyYWlzZSBBdHRyaWJ1dGVFcnJvciwgYXR0cgorCQorCWRlZiBfX3NldGF0dHJfXyhzZWxmLCBhdHRyLCB2YWx1ZSk6CisJCWlmIGF0dHJbMF0gPD4gJ18nOgorCQkJc2VsZi5fcHJlZnNkaWN0W2F0dHJdID0gdmFsdWUKKwkJZWxzZToKKwkJCXNlbGYuX19kaWN0X19bYXR0cl0gPSB2YWx1ZQorCQorCWRlZiBnZXRwcmVmc2RpY3Qoc2VsZik6CisJCXJldHVybiBzZWxmLl9wcmVmc2RpY3QKKworCitjbGFzcyBQcmVmRmlsZShQcmVmT2JqZWN0KToKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgcGF0aCwgY3JlYXRvciA9ICdQeXRoJyk6CisJCSMgRmluZCB0aGUgcHJlZmVyZW5jZXMgZm9sZGVyIGFuZCBvdXIgcHJlZnMgZmlsZSwgY3JlYXRlIGlmIG5lZWRlZC4KKwkJc2VsZi5fX3BhdGggPSBwYXRoCisJCXNlbGYuX19jcmVhdG9yID0gY3JlYXRvcgorCQlzZWxmLl9wcmVmc2RpY3QgPSB7fQorCQl0cnk6CisJCQlwcmVmZGljdCA9IG1hcnNoYWwubG9hZChvcGVuKHNlbGYuX19wYXRoLCAncmInKSkKKwkJZXhjZXB0IElPRXJyb3I6CisJCQlwYXNzCisJCWVsc2U6CisJCQlmb3Iga2V5LCB2YWx1ZSBpbiBwcmVmZGljdC5pdGVtcygpOgorCQkJCWlmIHR5cGUodmFsdWUpID09IHR5cGVzLkRpY3RUeXBlOgorCQkJCQlzZWxmLl9wcmVmc2RpY3Rba2V5XSA9IFByZWZPYmplY3QodmFsdWUpCisJCQkJZWxzZToKKwkJCQkJc2VsZi5fcHJlZnNkaWN0W2tleV0gPSB2YWx1ZQorCQorCWRlZiBzYXZlKHNlbGYpOgorCQlwcmVmZGljdCA9IHt9CisJCWZvciBrZXksIHZhbHVlIGluIHNlbGYuX3ByZWZzZGljdC5pdGVtcygpOgorCQkJaWYgdHlwZSh2YWx1ZSkgPT0gdHlwZXMuSW5zdGFuY2VUeXBlOgorCQkJCXByZWZkaWN0W2tleV0gPSB2YWx1ZS5nZXRwcmVmc2RpY3QoKQorCQkJCWlmIG5vdCBwcmVmZGljdFtrZXldOgorCQkJCQlkZWwgcHJlZmRpY3Rba2V5XQorCQkJZWxzZToKKwkJCQlwcmVmZGljdFtrZXldID0gdmFsdWUKKwkJbWFyc2hhbC5kdW1wKHByZWZkaWN0LCBvcGVuKHNlbGYuX19wYXRoLCAnd2InKSkKKwkJZnNzID0gbWFjZnMuRlNTcGVjKHNlbGYuX19wYXRoKQorCQlmc3MuU2V0Q3JlYXRvclR5cGUoc2VsZi5fX2NyZWF0b3IsICdwcmVmJykKKwkKKwlkZWYgX19nZXRhdHRyX18oc2VsZiwgYXR0cik6CisJCWlmIGF0dHIgPT0gJ19fbWVtYmVyc19fJzoKKwkJCWtleXMgPSBzZWxmLl9wcmVmc2RpY3Qua2V5cygpCisJCQlrZXlzLnNvcnQoKQorCQkJcmV0dXJuIGtleXMKKwkJdHJ5OgorCQkJcmV0dXJuIHNlbGYuX3ByZWZzZGljdFthdHRyXQorCQlleGNlcHQgS2V5RXJyb3I6CisJCQlpZiBhdHRyWzBdIDw+ICdfJzoKKwkJCQlzZWxmLl9wcmVmc2RpY3RbYXR0cl0gPSBQcmVmT2JqZWN0KCkKKwkJCQlyZXR1cm4gc2VsZi5fcHJlZnNkaWN0W2F0dHJdCisJCQllbHNlOgorCQkJCXJhaXNlIEF0dHJpYnV0ZUVycm9yLCBhdHRyCisKKworX3ByZWZzY2FjaGUgPSB7fQorCitkZWYgR2V0UHJlZnMocHJlZm5hbWUsIGNyZWF0b3IgPSAnUHl0aCcpOgorCWlmIF9wcmVmc2NhY2hlLmhhc19rZXkocHJlZm5hbWUpOgorCQlyZXR1cm4gX3ByZWZzY2FjaGVbcHJlZm5hbWVdCisJIyBGaW5kIHRoZSBwcmVmZXJlbmNlcyBmb2xkZXIgYW5kIG91ciBwcmVmcyBmaWxlLCBjcmVhdGUgaWYgbmVlZGVkLgorCXZyZWZudW0sIGRpcmlkID0gbWFjZnMuRmluZEZvbGRlcihrT25TeXN0ZW1EaXNrLCAncHJlZicsIDApCisJcHJlZnNmb2xkZXJfZnNzID0gbWFjZnMuRlNTcGVjKCh2cmVmbnVtLCBkaXJpZCwgJycpKQorCXByZWZzZm9sZGVyID0gcHJlZnNmb2xkZXJfZnNzLmFzX3BhdGhuYW1lKCkKKwlwYXRoID0gb3MucGF0aC5qb2luKHByZWZzZm9sZGVyLCBwcmVmbmFtZSkKKwloZWFkLCB0YWlsID0gb3MucGF0aC5zcGxpdChwYXRoKQorCSMgbWFrZSBzdXJlIHRoZSBmb2xkZXIocykgZXhpc3QKKwltYWNvc3Rvb2xzLm1rZGlycyhoZWFkKQorCQorCXByZWZmaWxlID0gUHJlZkZpbGUocGF0aCwgY3JlYXRvcikKKwlfcHJlZnNjYWNoZVtwcmVmbmFtZV0gPSBwcmVmZmlsZQorCXJldHVybiBwcmVmZmlsZQpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL01vZHVsZUJyb3dzZXIucHkgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvTW9kdWxlQnJvd3Nlci5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi42NzY4NWI4Ci0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL01vZHVsZUJyb3dzZXIucHkKQEAgLTAsMCArMSwxNjQgQEAKK2ltcG9ydCBXCitpbXBvcnQgc3lzCisKK19fdmVyc2lvbl9fID0gIjAuMiIKK19fYXV0aG9yX18gPSAianZyIgorCitjbGFzcyBfbW9kdWxlYnJvd3NlcjoKKwkKKwlkZWYgX19pbml0X18oc2VsZik6CisJCXNlbGYuZWRpdG1vZHVsZXMgPSBbXQorCQlzZWxmLm1vZHVsZXMgPSBbXQorCQlzZWxmLndpbmRvdyA9IFcuV2luZG93KCgxOTQsIDEwMDApLCAiTW9kdWxlIEJyb3dzZXIiLCBtaW5zaXplID0gKDE5NCwgMTYwKSwgbWF4c2l6ZSA9ICgzNDAsIDIwMDAwKSkKKwkJCisJCXNlbGYud2luZG93Lm9wZW5idXR0b24gPSBXLkJ1dHRvbigoMTAsIDgsIDgwLCAxNiksICJPcGVuIiwgc2VsZi5vcGVuYnV0dG9uaGl0KQorCQlzZWxmLndpbmRvdy5icm93c2VidXR0b24gPSBXLkJ1dHRvbigoMTAwLCA4LCA4MCwgMTYpLCAiQnJvd3NliiIsIHNlbGYuYnJvd3NlYnV0dG9uaGl0KQorCQlzZWxmLndpbmRvdy5yZWxvYWRidXR0b24gPSBXLkJ1dHRvbigoMTAsIDMyLCA4MCwgMTYpLCAiUmVsb2FkIiwgc2VsZi5yZWxvYWRidXR0b25oaXQpCisJCXNlbGYud2luZG93Lm9wZW5vdGhlcmJ1dHRvbiA9IFcuQnV0dG9uKCgxMDAsIDMyLCA4MCwgMTYpLCAiT3BlbiBvdGhlcooiLCBzZWxmLm9wZW5vdGhlcikKKwkJCisJCXNlbGYud2luZG93Lm9wZW5idXR0b24uZW5hYmxlKDApCisJCXNlbGYud2luZG93LnJlbG9hZGJ1dHRvbi5lbmFibGUoMCkKKwkJc2VsZi53aW5kb3cuYnJvd3NlYnV0dG9uLmVuYWJsZSgwKQorCQlzZWxmLndpbmRvdy5zZXRkZWZhdWx0YnV0dG9uKHNlbGYud2luZG93LmJyb3dzZWJ1dHRvbikKKwkJCisJCXNlbGYud2luZG93LmJpbmQoImNtZHIiLCBzZWxmLndpbmRvdy5yZWxvYWRidXR0b24ucHVzaCkKKwkJc2VsZi53aW5kb3cuYmluZCgiY21kYiIsIHNlbGYud2luZG93LmJyb3dzZWJ1dHRvbi5wdXNoKQorCQorCQlzZWxmLndpbmRvdy5iaW5kKCI8YWN0aXZhdGU+Iiwgc2VsZi5hY3RpdmF0ZSkKKwkJc2VsZi53aW5kb3cuYmluZCgiPGNsb3NlPiIsIHNlbGYuY2xvc2UpCisJCQorCQlzZWxmLndpbmRvdy5saXN0ID0gVy5MaXN0KCgtMSwgNTYsIDEsIC0xNCksIFtdLCBzZWxmLmxpc3RoaXQpCisJCQorCQlzZWxmLndpbmRvdy5vcGVuKCkKKwkJc2VsZi5jaGVja2J1dHRvbnMoKQorCQorCWRlZiBjbG9zZShzZWxmKToKKwkJZ2xvYmFsIF9icm93c2VyCisJCV9icm93c2VyID0gTm9uZQorCQorCWRlZiBhY3RpdmF0ZShzZWxmLCBvbm9mZik6CisJCWlmIG9ub2ZmOgorCQkJc2VsZi5tYWtlbGlzdCgpCisJCQorCWRlZiBsaXN0aGl0KHNlbGYsIGlzZGJsKToKKwkJc2VsZi5jaGVja2J1dHRvbnMoKQorCQlpZiBpc2RibDoKKwkJCWlmIHNlbGYud2luZG93Ll9kZWZhdWx0YnV0dG9uOgorCQkJCXNlbGYud2luZG93Ll9kZWZhdWx0YnV0dG9uLnB1c2goKQorCQorCWRlZiBjaGVja2J1dHRvbnMoc2VsZik6CisJCXNlbCA9IHNlbGYud2luZG93Lmxpc3QuZ2V0c2VsZWN0aW9uKCkKKwkJaWYgc2VsOgorCQkJZm9yIGkgaW4gc2VsOgorCQkJCWlmIHNlbGYuZWRpdG1vZHVsZXNbaV06CisJCQkJCXNlbGYud2luZG93Lm9wZW5idXR0b24uZW5hYmxlKDEpCisJCQkJCXNlbGYud2luZG93LnJlbG9hZGJ1dHRvbi5lbmFibGUoMSkKKwkJCQkJc2VsZi53aW5kb3cuc2V0ZGVmYXVsdGJ1dHRvbihzZWxmLndpbmRvdy5vcGVuYnV0dG9uKQorCQkJCQlicmVhaworCQkJZWxzZToKKwkJCQlzZWxmLndpbmRvdy5vcGVuYnV0dG9uLmVuYWJsZSgwKQorCQkJCXNlbGYud2luZG93LnJlbG9hZGJ1dHRvbi5lbmFibGUoMCkKKwkJCQlzZWxmLndpbmRvdy5zZXRkZWZhdWx0YnV0dG9uKHNlbGYud2luZG93LmJyb3dzZWJ1dHRvbikKKwkJCXNlbGYud2luZG93LmJyb3dzZWJ1dHRvbi5lbmFibGUoMSkKKwkJZWxzZToKKwkJCSNzZWxmLndpbmRvdy5zZXRkZWZhdWx0YnV0dG9uKHNlbGYud2luZG93LmJyb3dzZWJ1dHRvbikKKwkJCXNlbGYud2luZG93Lm9wZW5idXR0b24uZW5hYmxlKDApCisJCQlzZWxmLndpbmRvdy5yZWxvYWRidXR0b24uZW5hYmxlKDApCisJCQlzZWxmLndpbmRvdy5icm93c2VidXR0b24uZW5hYmxlKDApCisJCisJZGVmIG9wZW5idXR0b25oaXQoc2VsZik6CisJCWltcG9ydCBpbXAKKwkJc2VsID0gc2VsZi53aW5kb3cubGlzdC5nZXRzZWxlY3Rpb24oKQorCQlXLlNldEN1cnNvcigid2F0Y2giKQorCQlmb3IgaSBpbiBzZWw6CisJCQltb2RuYW1lID0gc2VsZi53aW5kb3cubGlzdFtpXQorCQkJdHJ5OgorCQkJCXNlbGYub3BlbnNjcmlwdChzeXMubW9kdWxlc1ttb2RuYW1lXS5fX2ZpbGVfXywgbW9kbmFtZSkKKwkJCWV4Y2VwdCBJT0Vycm9yOgorCQkJCXRyeToKKwkJCQkJZmlsZSwgcGF0aCwgZGVzY3JpcHRpb24gPSBpbXAuZmluZF9tb2R1bGUobW9kbmFtZSkKKwkJCQlleGNlcHQgSW1wb3J0RXJyb3I6CisJCQkJCVcuU2V0Q3Vyc29yKCJhcnJvdyIpCisJCQkJCVcuTWVzc2FnZSgiQ2FuuXQgZmluZCBmaWxlIGZvciBtb2R1bGUgsyVzsi4iIAorCQkJCQkJCSUgbW9kbmFtZSkKKwkJCQllbHNlOgorCQkJCQlzZWxmLm9wZW5zY3JpcHQocGF0aCwgbW9kbmFtZSkJCQkJCQorCQorCWRlZiBvcGVuc2NyaXB0KHNlbGYsIHBhdGgsIG1vZG5hbWUpOgorCQlpZiBwYXRoWy0zOl0gPT0gJy5weSc6CisJCQlXLmdldGFwcGxpY2F0aW9uKCkub3BlbnNjcmlwdChwYXRoKQorCQllbHNlOgorCQkJVy5NZXNzYWdlKCJDYW65dCBlZGl0ILMlc7I7IGl0IG1pZ2h0IGJlIGEgc2hhcmVkIGxpYnJhcnkgb3IgYSAucHljIGZpbGUuIiAKKwkJCQkJJSBtb2RuYW1lKQorCQorCWRlZiBvcGVub3RoZXIoc2VsZik6CisJCWltcG9ydCBpbXAKKwkJaW1wb3J0IEVhc3lEaWFsb2dzCisJCQorCQltb2RuYW1lID0gRWFzeURpYWxvZ3MuQXNrU3RyaW5nKCJPcGVuIG1vZHVsZToiKQorCQlpZiBtb2RuYW1lOgorCQkJdHJ5OgorCQkJCWZpbGUsIHBhdGgsIGRlc2NyaXB0aW9uID0gaW1wLmZpbmRfbW9kdWxlKG1vZG5hbWUpCisJCQlleGNlcHQgSW1wb3J0RXJyb3I6CisJCQkJaWYgbW9kbmFtZSBpbiBzeXMuYnVpbHRpbl9tb2R1bGVfbmFtZXM6CisJCQkJCWFsZXJ0dGV4dCA9ICKzJXOyIGlzIGEgYnVpbHRpbiBtb2R1bGUsIHdoaWNoIHlvdSBjYW65dCBlZGl0LiIgJSBtb2RuYW1lCisJCQkJZWxzZToKKwkJCQkJYWxlcnR0ZXh0ID0gIk5vIG1vZHVsZSBuYW1lZCCzJXOyLiIgJSBtb2RuYW1lCisJCQkJcmFpc2UgVy5BbGVydEVycm9yLCBhbGVydHRleHQKKwkJCXNlbGYub3BlbnNjcmlwdChwYXRoLCBtb2RuYW1lKQorCQorCWRlZiByZWxvYWRidXR0b25oaXQoc2VsZik6CisJCXNlbCA9IHNlbGYud2luZG93Lmxpc3QuZ2V0c2VsZWN0aW9uKCkKKwkJVy5TZXRDdXJzb3IoIndhdGNoIikKKwkJZm9yIGkgaW4gc2VsOgorCQkJbSA9IHN5cy5tb2R1bGVzW3NlbGYud2luZG93Lmxpc3RbaV1dCisJCQlyZWxvYWQobSkKKwkKKwlkZWYgYnJvd3NlYnV0dG9uaGl0KHNlbGYpOgorCQlzZWwgPSBzZWxmLndpbmRvdy5saXN0LmdldHNlbGVjdGlvbigpCisJCWlmIG5vdCBzZWw6CisJCQlyZXR1cm4KKwkJaW1wb3J0IFB5QnJvd3NlcgorCQlmb3IgaSBpbiBzZWw6CisJCQlQeUJyb3dzZXIuQnJvd3NlcihzeXMubW9kdWxlc1tzZWxmLndpbmRvdy5saXN0W2ldXSkKKwkKKwlkZWYgbWFrZWxpc3Qoc2VsZik6CisJCWVkaXRtb2R1bGVzLCBtb2R1bGVzID0gZ2V0bW9kdWxlc2xpc3QoKQorCQlpZiBtb2R1bGVzID09IHNlbGYubW9kdWxlczoKKwkJCXJldHVybgorCQlzZWxmLmVkaXRtb2R1bGVzLCBzZWxmLm1vZHVsZXMgPSBlZGl0bW9kdWxlcywgbW9kdWxlcworCQlzZWxmLndpbmRvdy5saXN0LnNldGRyYXdpbmdtb2RlKDApCisJCXNlbCA9IHNlbGYud2luZG93Lmxpc3QuZ2V0c2VsZWN0ZWRvYmplY3RzKCkKKwkJc2VsZi53aW5kb3cubGlzdC5zZXQoc2VsZi5tb2R1bGVzKQorCQlzZWxmLndpbmRvdy5saXN0LnNldHNlbGVjdGVkb2JqZWN0cyhzZWwpCisJCXNlbGYud2luZG93Lmxpc3Quc2V0ZHJhd2luZ21vZGUoMSkKKworCitkZWYgZ2V0bW9kdWxlc2xpc3QoKToKKwlpbXBvcnQgUHlCcm93c2VyCSMgZm9yIGNhc2VsZXNzc29ydCBmdW5jdGlvbgorCW1vZHVsZXMgPSBzeXMubW9kdWxlcy5rZXlzKCkKKwltb2R1bGVzID0gUHlCcm93c2VyLmNhc2VsZXNzc29ydChtb2R1bGVzKQorCWVkaXRtb2R1bGVzID0gW10KKwlzeXNtb2R1bGVzID0gc3lzLm1vZHVsZXMKKwltb2R1bGVzYXBwZW5kID0gZWRpdG1vZHVsZXMuYXBwZW5kCisJZm9yIG0gaW4gbW9kdWxlczoKKwkJbW9kdWxlID0gc3lzbW9kdWxlc1ttXQorCQl0cnk6CisJCQlpZiBzeXNtb2R1bGVzW21dLl9fZmlsZV9fWy0zOl0gPT0gJy5weSc6CisJCQkJbW9kdWxlc2FwcGVuZCgxKQorCQkJZWxzZToKKwkJCQltb2R1bGVzYXBwZW5kKDApCisJCWV4Y2VwdCBBdHRyaWJ1dGVFcnJvcjoKKwkJCW1vZHVsZXNhcHBlbmQoMCkKKwlyZXR1cm4gZWRpdG1vZHVsZXMsIG1vZHVsZXMKKwkKKwkKKworX2Jyb3dzZXIgPSBOb25lCisKK2RlZiBNb2R1bGVCcm93c2VyKCk6CisJZ2xvYmFsIF9icm93c2VyCisJaWYgX2Jyb3dzZXIgaXMgbm90IE5vbmU6CisJCV9icm93c2VyLndpbmRvdy5zZWxlY3QoKQorCWVsc2U6CisJCV9icm93c2VyID0gX21vZHVsZWJyb3dzZXIoKQpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1Byb2ZpbGVCcm93c2VyLnB5IGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1Byb2ZpbGVCcm93c2VyLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjcxMDQ4MWMKLS0tIC9kZXYvbnVsbAorKysgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvUHJvZmlsZUJyb3dzZXIucHkKQEAgLTAsMCArMSw4MiBAQAoraW1wb3J0IFcKK2ltcG9ydCBFdnQKKworaW1wb3J0IHN5cworaW1wb3J0IFN0cmluZ0lPCitpbXBvcnQgc3RyaW5nCisKK2RlZiB0aW1lcihUaWNrQ291bnQgPSBFdnQuVGlja0NvdW50KToKKwlyZXR1cm4gVGlja0NvdW50KCkgLyA2MC4wCisKK2NsYXNzIFByb2ZpbGVCcm93c2VyOgorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBzdGF0cyA9IE5vbmUpOgorCQlzZWxmLnNvcnRrZXlzID0gKCdjYWxscycsKQorCQlzZWxmLnNldHVwd2lkZ2V0cygpCisJCXNlbGYuc2V0c3RhdHMoc3RhdHMpCisJCisJZGVmIHNldHVwd2lkZ2V0cyhzZWxmKTogCisJCXNlbGYudyA9IFcuV2luZG93KCg1ODAsIDQwMCksICJQcm9maWxlIFN0YXRpc3RpY3MiLCBtaW5zaXplID0gKDIwMCwgMTAwKSwgdGFiYmFibGUgPSAwKQorCQlzZWxmLncuZGl2bGluZSA9IFcuSG9yaXpvbnRhbExpbmUoKDAsIDIwLCAwLCAwKSkKKwkJc2VsZi53LnRpdGxlYmFyID0gVy5UZXh0Qm94KCg0LCA0LCA0MCwgMTIpLCAnU29ydCBieTonKQorCQlzZWxmLmJ1dHRvbnMgPSBbXQorCQlzZWxmLncuYnV0dG9uX2NhbGxzID0gVy5SYWRpb0J1dHRvbigoNTQsIDQsIDQ1LCAxMiksICdjYWxscycsIHNlbGYuYnV0dG9ucywgc2VsZi5zZXRzb3J0KQorCQlzZWxmLncuYnV0dG9uX3RpbWUgPSBXLlJhZGlvQnV0dG9uKCgxMDQsIDQsIDQwLCAxMiksICd0aW1lJywgc2VsZi5idXR0b25zLCBzZWxmLnNldHNvcnQpCisJCXNlbGYudy5idXR0b25fY3VtdWxhdGl2ZSA9IFcuUmFkaW9CdXR0b24oKDE1NCwgNCwgNzUsIDEyKSwgJ2N1bXVsYXRpdmUnLCBzZWxmLmJ1dHRvbnMsIHNlbGYuc2V0c29ydCkKKwkJc2VsZi53LmJ1dHRvbl9zdGRuYW1lID0gVy5SYWRpb0J1dHRvbigoMjM0LCA0LCA2MCwgMTIpLCAnc3RkbmFtZScsIHNlbGYuYnV0dG9ucywgc2VsZi5zZXRzb3J0KQorCQlzZWxmLncuYnV0dG9uX2NhbGxzLnNldCgxKQorCQlzZWxmLncuYnV0dG9uX2ZpbGUgPSBXLlJhZGlvQnV0dG9uKCgzMDQsIDQsIDQwLCAxMiksICdmaWxlJywgc2VsZi5idXR0b25zLCBzZWxmLnNldHNvcnQpCisJCXNlbGYudy5idXR0b25fbGluZSA9IFcuUmFkaW9CdXR0b24oKDM1NCwgNCwgNTAsIDEyKSwgJ2xpbmUnLCBzZWxmLmJ1dHRvbnMsIHNlbGYuc2V0c29ydCkKKwkJc2VsZi53LmJ1dHRvbl9tb2R1bGUgPSBXLlJhZGlvQnV0dG9uKCg0MDQsIDQsIDU1LCAxMiksICdtb2R1bGUnLCBzZWxmLmJ1dHRvbnMsIHNlbGYuc2V0c29ydCkKKwkJc2VsZi53LmJ1dHRvbl9uYW1lID0gVy5SYWRpb0J1dHRvbigoNDY0LCA0LCA1MCwgMTIpLCAnbmFtZScsIHNlbGYuYnV0dG9ucywgc2VsZi5zZXRzb3J0KQorIyMJCXNlbGYudy5idXR0b25fbmZsID0gVy5SYWRpb0J1dHRvbigoNCwgNCwgMTIsIDEyKSwgJ25mbCcsIHNlbGYuYnV0dG9ucywgc2VsZi5zZXRzb3J0KQorIyMJCXNlbGYudy5idXR0b25fcGNhbGxzID0gVy5SYWRpb0J1dHRvbigoNCwgNCwgMTIsIDEyKSwgJ3BjYWxscycsIHNlbGYuYnV0dG9ucywgc2VsZi5zZXRzb3J0KQorCQlzZWxmLncudGV4dCA9IFcuVGV4dEVkaXRvcigoMCwgMjEsIC0xNSwgLTE1KSwgaW5zZXQgPSAoNiwgNSksIAorCQkJCXJlYWRvbmx5ID0gMSwgd3JhcCA9IDAsIGZvbnRzZXR0aW5ncyA9ICgnTW9uYWNvJywgMCwgOSwgKDAsIDAsIDApKSkKKwkJc2VsZi53Ll9iYXJ5ID0gVy5TY3JvbGxiYXIoKC0xNSwgMjAsIDE2LCAtMTQpLCBzZWxmLncudGV4dC52c2Nyb2xsLCBtYXggPSAzMjc2NykKKwkJc2VsZi53Ll9iYXJ4ID0gVy5TY3JvbGxiYXIoKC0xLCAtMTUsIC0xNCwgMTYpLCBzZWxmLncudGV4dC5oc2Nyb2xsLCBtYXggPSAzMjc2NykKKwkJc2VsZi53Lm9wZW4oKQorCQorCWRlZiBzZXRzdGF0cyhzZWxmLCBzdGF0cyk6CisJCXNlbGYuc3RhdHMgPSBzdGF0cworCQlzZWxmLnN0YXRzLnN0cmlwX2RpcnMoKQorCQlzZWxmLmRpc3BsYXlzdGF0cygpCisJCisJZGVmIHNldHNvcnQoc2VsZik6CisJCSMgR3JtcGYuIFRoZSBjYWxsYmFjayBkb2Vzbid0IGdpdmUgdXMgdGhlIGJ1dHRvbjotKAorCQlmb3IgYiBpbiBzZWxmLmJ1dHRvbnM6CisJCQlpZiBiLmdldCgpOgorCQkJCWlmIGIuX3RpdGxlID09IHNlbGYuc29ydGtleXNbMF06CisJCQkJCXJldHVybgorCQkJCXNlbGYuc29ydGtleXMgPSAoYi5fdGl0bGUsKSArIHNlbGYuc29ydGtleXNbOjNdCisJCQkJYnJlYWsKKwkJc2VsZi5kaXNwbGF5c3RhdHMoKQorCQorCWRlZiBkaXNwbGF5c3RhdHMoc2VsZik6CisJCVcuU2V0Q3Vyc29yKCd3YXRjaCcpCisJCWFwcGx5KHNlbGYuc3RhdHMuc29ydF9zdGF0cywgc2VsZi5zb3J0a2V5cykKKwkJc2F2ZW91dCA9IHN5cy5zdGRvdXQKKwkJdHJ5OgorCQkJcyA9IHN5cy5zdGRvdXQgPSBTdHJpbmdJTy5TdHJpbmdJTygpCisJCQlzZWxmLnN0YXRzLnByaW50X3N0YXRzKCkKKwkJZmluYWxseToKKwkJCXN5cy5zdGRvdXQgPSBzYXZlb3V0CisJCXRleHQgPSBzdHJpbmcuam9pbihzdHJpbmcuc3BsaXQocy5nZXR2YWx1ZSgpLCAnXG4nKSwgJ1xyJykKKwkJc2VsZi53LnRleHQuc2V0KHRleHQpCisKKworZGVmIG1haW4oKToKKwlpbXBvcnQgcHN0YXRzCisJYXJncyA9IHN5cy5hcmd2WzE6XQorCWZvciBpIGluIGFyZ3M6CisJCXN0YXRzID0gcHN0YXRzLlN0YXRzKGkpCisJCWJyb3dzZXIgPSBQcm9maWxlQnJvd3NlcihzdGF0cykKKwllbHNlOgorCQlpbXBvcnQgbWFjZnMKKwkJZnNzLCBvayA9IG1hY2ZzLlByb21wdEdldEZpbGUoJ1Byb2ZpbGVyIGRhdGEnKQorCQlpZiBub3Qgb2s6IHN5cy5leGl0KDApCisJCXN0YXRzID0gcHN0YXRzLlN0YXRzKGZzcy5hc19wYXRobmFtZSgpKQorCQlicm93c2VyID0gUHJvZmlsZUJyb3dzZXIoc3RhdHMpCisKK2lmIF9fbmFtZV9fID09ICdfX21haW5fXyc6CisJbWFpbigpCmRpZmYgLS1naXQgYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvUHlCcm93c2VyLnB5IGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1B5QnJvd3Nlci5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44ZDVmNDZjCi0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1B5QnJvd3Nlci5weQpAQCAtMCwwICsxLDQzOSBAQAoraW1wb3J0IFcsIFNwZWNpYWxLZXlzCitpbXBvcnQgc3RydWN0CitpbXBvcnQgc3RyaW5nCitpbXBvcnQgdHlwZXMKK2ltcG9ydCByZWdleAorCitudWxsaWQgPSAnXDBcMCcKK2Nsb3NlZGlkID0gc3RydWN0LnBhY2soJ2gnLCA0NjgpCitvcGVuaWQgPSBzdHJ1Y3QucGFjaygnaCcsIDQ2OSkKK2Nsb3NlZHNvbGlkaWQgPSBzdHJ1Y3QucGFjaygnaCcsIDQ3MCkKK29wZW5zb2xpZGlkID0gc3RydWN0LnBhY2soJ2gnLCA0NzEpCisKK2Fycm93cyA9IChudWxsaWQsIGNsb3NlZGlkLCBvcGVuaWQsIGNsb3NlZHNvbGlkaWQsIG9wZW5zb2xpZGlkKQorCitoYXNfY3RsY2hhcnNSRSA9IHJlZ2V4LmNvbXBpbGUoJ1tcMDAwLVwwMzdcMTc3LVwzNzddJykKKworZGVmIGRvdWJsZV9yZXByKGtleSwgdmFsdWUsIHRydW5jdmFsdWUgPSAwLCAKKwkJCXR5cGUgPSB0eXBlLCBTdHJpbmdUeXBlID0gdHlwZXMuU3RyaW5nVHlwZSwKKwkJCWhhc19jdGxjaGFycyA9IGhhc19jdGxjaGFyc1JFLnNlYXJjaCwgX3JlcHIgPSByZXByLCBzdHIgPSBzdHIpOgorCWlmIHR5cGUoa2V5KSA9PSBTdHJpbmdUeXBlIGFuZCBoYXNfY3RsY2hhcnMoa2V5KSA8IDA6CisJCWtleSA9IHN0cihrZXkpCisJZWxzZToKKwkJa2V5ID0gX3JlcHIoa2V5KQorCWlmIHR5cGUodmFsdWUpID09IFN0cmluZ1R5cGUgYW5kIGhhc19jdGxjaGFycyh2YWx1ZSkgPCAwOgorCQl2YWx1ZSA9IHN0cih2YWx1ZSkKKwllbGlmIGtleSA9PSAnX19idWlsdGluc19fJzoKKwkJdmFsdWUgPSAiPCIgKyB0eXBlKHZhbHVlKS5fX25hbWVfXyArICIgJ19fYnVpbHRpbl9fJz4iCisJZWxpZiBrZXkgPT0gJ19fcmV0dXJuX18nOgorCQkjIGJsZWgsIHdoZW4gcmV0dXJuaW5nIGZyb20gYSBjbGFzcyBjb2RlYmxvY2sgd2UgZ2V0IGluZmluaXRlIHJlY3Vyc2lvbiBpbiByZXByLiAKKwkJIyBVc2Ugc2FmZSByZXByIGluc3RlYWQuCisJCWltcG9ydCByZXByCisJCXZhbHVlID0gcmVwci5yZXByKHZhbHVlKQorCWVsc2U6CisJCXRyeToKKwkJCXZhbHVlID0gX3JlcHIodmFsdWUpCisJCQknJyArIHZhbHVlCSMgdGVzdCB0byBzZWUgaWYgaXQgaXMgYSBzdHJpbmcsIGluIGNhc2UgYSBfX3JlcHJfXyBtZXRob2QgaXMgYnVnZ3kKKwkJZXhjZXB0OgorCQkJdmFsdWUgPSAngICAIGV4Y2VwdGlvbiBpbiByZXByKCknCisJaWYgdHJ1bmN2YWx1ZToKKwkJcmV0dXJuIGtleSArICdcdCcgKyB2YWx1ZVs6MjU1XQorCXJldHVybiBrZXkgKyAnXHQnICsgdmFsdWUKKworCitjbGFzcyBCcm93c2VyV2lkZ2V0KFcuTGlzdCk6CisJCisJTERFRl9JRCA9IDQ3MQorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBwb3NzaXplLCBvYmplY3QgPSBOb25lLCBjb2wgPSAxMDAsIGNsb3NlY2hpbGRyZW4gPSAwKToKKwkJVy5MaXN0Ll9faW5pdF9fKHNlbGYsIHBvc3NpemUsIGNhbGxiYWNrID0gc2VsZi5saXN0aGl0KQorCQlzZWxmLm9iamVjdCA9IE5vbmUsCisJCXNlbGYuaW5kZW50ID0gMTYKKwkJc2VsZi5sYXN0bWF4aW5kZW50ID0gMAorCQlzZWxmLmNsb3NlY2hpbGRyZW4gPSBjbG9zZWNoaWxkcmVuCisJCXNlbGYuY2hpbGRyZW4gPSBbXQorCQlzZWxmLm1pbmNvbCA9IDY0CisJCXNlbGYuc2V0Y29sdW1uKGNvbCkKKwkJc2VsZi5iaW5kKCdyZXR1cm4nLCBzZWxmLm9wZW5zZWxlY3Rpb24pCisJCXNlbGYuYmluZCgnZW50ZXInLCBzZWxmLm9wZW5zZWxlY3Rpb24pCisJCWlmIG9iamVjdCBpcyBub3QgTm9uZToKKwkJCXNlbGYuc2V0KG9iamVjdCkKKwkKKwlkZWYgc2V0KHNlbGYsIG9iamVjdCk6CisJCWlmIHNlbGYub2JqZWN0WzBdIDw+IG9iamVjdDoKKwkJCXNlbGYub2JqZWN0ID0gb2JqZWN0LAorCQkJc2VsZls6XSA9IHNlbGYudW5wYWNrKG9iamVjdCwgMCkKKwkJZWxpZiBzZWxmLl9wYXJlbnR3aW5kb3cgaXMgbm90IE5vbmUgYW5kIHNlbGYuX3BhcmVudHdpbmRvdy53aWQ6CisJCQlzZWxmLnVwZGF0ZSgpCisJCisJZGVmIHVucGFjayhzZWxmLCBvYmplY3QsIGluZGVudCk6CisJCXJldHVybiB1bnBhY2tfb2JqZWN0KG9iamVjdCwgaW5kZW50KQorCQorCWRlZiB1cGRhdGUoc2VsZik6CisJCSMgZm9yIG5vdy4uLgorCQlXLlNldEN1cnNvcignd2F0Y2gnKQorCQlzZWxmLnNldGRyYXdpbmdtb2RlKDApCisJCXNlbCA9IHNlbGYuZ2V0c2VsZWN0ZWRvYmplY3RzKCkKKwkJZm9sZCA9IHNlbGYuZ2V0dW5mb2xkZWRvYmplY3RzKCkKKwkJdG9wY2VsbCA9IHNlbGYuZ2V0dG9wY2VsbCgpCisJCXNlbGZbOl0gPSBzZWxmLnVucGFjayhzZWxmLm9iamVjdFswXSwgMCkKKwkJc2VsZi51bmZvbGRvYmplY3RzKGZvbGQpCisJCXNlbGYuc2V0c2VsZWN0ZWRvYmplY3RzKHNlbCkKKwkJc2VsZi5zZXR0b3BjZWxsKHRvcGNlbGwpCisJCXNlbGYuc2V0ZHJhd2luZ21vZGUoMSkKKwkKKwlkZWYgc2V0Y29sdW1uKHNlbGYsIGNvbCk6CisJCXNlbGYuY29sID0gY29sCisJCXNlbGYuY29sc3RyID0gc3RydWN0LnBhY2soJ2gnLCBjb2wpCisJCWlmIHNlbGYuX2xpc3Q6CisJCQlzZWwgPSBzZWxmLmdldHNlbGVjdGlvbigpCisJCQlzZWxmLnNldGl0ZW1zKHNlbGYuaXRlbXMpCisJCQlzZWxmLnNldHNlbGVjdGlvbihzZWwpCisJCisJZGVmIGtleShzZWxmLCBjaGFyLCBldmVudCk6CisJCWlmIGNoYXIgaW4gKFNwZWNpYWxLZXlzLmxlZnRhcnJvd2tleSwgU3BlY2lhbEtleXMucmlnaHRhcnJvd2tleSk6CisJCQlzZWwgPSBzZWxmLmdldHNlbGVjdGlvbigpCisJCQlzZWwucmV2ZXJzZSgpCisJCQlzZWxmLnNldGRyYXdpbmdtb2RlKDApCisJCQlmb3IgaW5kZXggaW4gc2VsOgorCQkJCXNlbGYuZm9sZChpbmRleCwgY2hhciA9PSBTcGVjaWFsS2V5cy5yaWdodGFycm93a2V5KQorCQkJc2VsZi5zZXRkcmF3aW5nbW9kZSgxKQorCQllbHNlOgorCQkJVy5MaXN0LmtleShzZWxmLCBjaGFyLCBldmVudCkKKwkKKwlkZWYgcm9sbG92ZXIoc2VsZiwgKHgsIHkpLCBvbm9mZik6CisJCWlmIG9ub2ZmOgorCQkJaWYgc2VsZi5pbmNvbHVtbigoeCwgeSkpOgorCQkJCVcuU2V0Q3Vyc29yKCdobW92ZXInKQorCQkJZWxzZToKKwkJCQlXLlNldEN1cnNvcignYXJyb3cnKQorCQorCWRlZiBpbmFycm93KHNlbGYsICh4LCB5KSk6CisJCWNsLCBjdCwgY3IsIGNiID0gc2VsZi5fbGlzdC5MUmVjdCgoMCwgMCkpCisJCWwsIHQsIHIsIGIgPSBzZWxmLl9ib3VuZHMKKwkJaWYgKHggLSBjbCkgPCAxNjoKKwkJCWNlbGxoZWlnaHQgPSBjYiAtIGN0CisJCQlpbmRleCA9ICh5IC0gY3QpIC8gY2VsbGhlaWdodAorCQkJaWYgaW5kZXggPCBsZW4oc2VsZi5pdGVtcyk6CisJCQkJcmV0dXJuIDEsIGluZGV4CisJCXJldHVybiBOb25lLCBOb25lCisJCisJZGVmIGluY29sdW1uKHNlbGYsICh4LCB5KSk6CisJCWwsIHQsIHIsIGIgPSBzZWxmLl9saXN0LkxSZWN0KCgwLCAwKSkKKwkJYWJzY29sID0gbCArIHNlbGYuY29sCisJCXJldHVybiBhYnMoYWJzY29sIC0geCkgPCAzCisJCisJZGVmIHRyYWNrY29sdW1uKHNlbGYsICh4LCB5KSk6CisJCWltcG9ydCBRZCwgUXVpY2tEcmF3LCBFdnQKKwkJc2VsZi5TZXRQb3J0KCkKKwkJbCwgdCwgciwgYiA9IHNlbGYuX2JvdW5kcworCQlib3VuZHMgPSBsLCB0LCByLCBiID0gbCArIDEsIHQgKyAxLCByIC0gMTYsIGIgLSAxCisJCWFic2NvbCA9IGwgKyBzZWxmLmNvbAorCQltaW5jb2wgPSBsICsgc2VsZi5taW5jb2wKKwkJbWF4Y29sID0gciAtIDEwCisJCWRpZmYgPSBhYnNjb2wgLSB4CisJCVFkLlBlblBhdCgnXDAwMFwzNzdcMDAwXDM3N1wwMDBcMzc3XDAwMFwzNzcnKQorCQlRZC5QZW5Nb2RlKFF1aWNrRHJhdy5zcmNYb3IpCisJCXJlY3QgPSBhYnNjb2wgLSAxLCB0LCBhYnNjb2wsIGIKKwkJUWQuUGFpbnRSZWN0KHJlY3QpCisJCWxhc3Rwb2ludCA9ICh4LCB5KQorCQluZXdjb2wgPSAtMQorCQkjVy5TZXRDdXJzb3IoJ2Zpc3QnKQorCQl3aGlsZSBFdnQuQnV0dG9uKCk6CisJCQkoeCwgeSkgPSBFdnQuR2V0TW91c2UoKQorCQkJaWYgKHgsIHkpIDw+IGxhc3Rwb2ludDoKKwkJCQluZXdjb2wgPSB4ICsgZGlmZgorCQkJCW5ld2NvbCA9IG1heChuZXdjb2wsIG1pbmNvbCkKKwkJCQluZXdjb2wgPSBtaW4obmV3Y29sLCBtYXhjb2wpCisJCQkJUWQuUGFpbnRSZWN0KHJlY3QpCisJCQkJcmVjdCA9IG5ld2NvbCAtIDEsIHQsIG5ld2NvbCwgYgorCQkJCVFkLlBhaW50UmVjdChyZWN0KQorCQkJCWxhc3Rwb2ludCA9ICh4LCB5KQorCQlRZC5QYWludFJlY3QocmVjdCkKKwkJUWQuUGVuUGF0KFFkLnFkLmJsYWNrKQorCQlRZC5QZW5Ob3JtYWwoKQorCQlpZiBuZXdjb2wgPiAwIGFuZCBuZXdjb2wgPD4gYWJzY29sOgorCQkJc2VsZi5zZXRjb2x1bW4obmV3Y29sIC0gbCkKKwkKKwlkZWYgY2xpY2soc2VsZiwgcG9pbnQsIG1vZGlmaWVycyk6CisJCWlmIHBvaW50ID09ICgtMSwgLTEpOgkjIGdyb3NzLgorCQkJVy5MaXN0LmNsaWNrKHNlbGYsIHBvaW50ICxtb2RpZmllcnMpCisJCQlyZXR1cm4KKwkJaGl0LCBpbmRleCA9IHNlbGYuaW5hcnJvdyhwb2ludCkKKwkJaWYgaGl0OgorCQkJKGtleSwgdmFsdWUsIGFycm93LCBpbmRlbnQpID0gc2VsZi5pdGVtc1tpbmRleF0KKwkJCXNlbGYuZm9sZChpbmRleCwgYXJyb3cgPT0gMSkKKwkJZWxpZiBzZWxmLmluY29sdW1uKHBvaW50KToKKwkJCXNlbGYudHJhY2tjb2x1bW4ocG9pbnQpCisJCWVsc2U6CisJCQlXLkxpc3QuY2xpY2soc2VsZiwgcG9pbnQsIG1vZGlmaWVycykKKwkKKwkjIGZvciBXLkxpc3Qua2V5CisJZGVmIGZpbmRtYXRjaChzZWxmLCB0YWcpOgorCQlsb3dlciA9IHN0cmluZy5sb3dlcgorCQlpdGVtcyA9IHNlbGYuaXRlbXMKKwkJdGFnbGVuID0gbGVuKHRhZykKKwkJbWF0Y2ggPSAnXDM3NycgKiAxMDAKKwkJbWF0Y2hfaSA9IC0xCisJCWZvciBpIGluIHJhbmdlKGxlbihpdGVtcykpOgorCQkJaXRlbSA9IGxvd2VyKHN0cihpdGVtc1tpXVswXSkpCisJCQlpZiB0YWcgPD0gaXRlbSA8IG1hdGNoOgorCQkJCW1hdGNoID0gaXRlbQorCQkJCW1hdGNoX2kgPSBpCisJCWlmIG1hdGNoX2kgPj0gMDoKKwkJCXJldHVybiBtYXRjaF9pCisJCWVsc2U6CisJCQlyZXR1cm4gbGVuKGl0ZW1zKSAtIDEKKwkKKwlkZWYgY2xvc2Uoc2VsZik6CisJCWlmIHNlbGYuY2xvc2VjaGlsZHJlbjoKKwkJCWZvciB3aW5kb3cgaW4gc2VsZi5jaGlsZHJlbjoKKwkJCQl3aW5kb3cuY2xvc2UoKQorCQlzZWxmLmNoaWxkcmVuID0gW10KKwkJVy5MaXN0LmNsb3NlKHNlbGYpCisJCisJZGVmIGZvbGQoc2VsZiwgaW5kZXgsIG9ub2ZmKToKKwkJKGtleSwgdmFsdWUsIGFycm93LCBpbmRlbnQpID0gc2VsZi5pdGVtc1tpbmRleF0KKwkJaWYgYXJyb3cgPT0gMCBvciAob25vZmYgYW5kIGFycm93ID09IDIpIG9yIChub3Qgb25vZmYgYW5kIGFycm93ID09IDEpOgorCQkJcmV0dXJuCisJCVcuU2V0Q3Vyc29yKCd3YXRjaCcpCisJCXRvcGNlbGwgPSBzZWxmLmdldHRvcGNlbGwoKQorCQlpZiBvbm9mZjoKKwkJCXNlbGZbaW5kZXhdID0gKGtleSwgdmFsdWUsIDQsIGluZGVudCkKKwkJCXNlbGYuc2V0ZHJhd2luZ21vZGUoMCkKKwkJCXNlbGZbaW5kZXgrMTppbmRleCsxXSA9IHNlbGYudW5wYWNrKHZhbHVlLCBpbmRlbnQgKyAxKQorCQkJc2VsZltpbmRleF0gPSAoa2V5LCB2YWx1ZSwgMiwgaW5kZW50KQorCQllbHNlOgorCQkJc2VsZltpbmRleF0gPSAoa2V5LCB2YWx1ZSwgMywgaW5kZW50KQorCQkJc2VsZi5zZXRkcmF3aW5nbW9kZSgwKQorCQkJY291bnQgPSAwCisJCQlmb3IgaSBpbiByYW5nZShpbmRleCArIDEsIGxlbihzZWxmLml0ZW1zKSk6CisJCQkJKGR1bW15LCBkdW1teSwgZHVtbXksIHN1YmluZGVudCkgPSBzZWxmLml0ZW1zW2ldCisJCQkJaWYgc3ViaW5kZW50IDw9IGluZGVudDoKKwkJCQkJYnJlYWsKKwkJCQljb3VudCA9IGNvdW50ICsgMQorCQkJc2VsZltpbmRleCsxOmluZGV4KzErY291bnRdID0gW10KKwkJCXNlbGZbaW5kZXhdID0gKGtleSwgdmFsdWUsIDEsIGluZGVudCkKKwkJbWF4aW5kZW50ID0gc2VsZi5nZXRtYXhpbmRlbnQoKQorCQlpZiBtYXhpbmRlbnQgPD4gc2VsZi5sYXN0bWF4aW5kZW50OgorCQkJbmV3YWJzaW5kZW50ID0gc2VsZi5jb2wgKyAobWF4aW5kZW50IC0gc2VsZi5sYXN0bWF4aW5kZW50KSAqIHNlbGYuaW5kZW50CisJCQlpZiBuZXdhYnNpbmRlbnQgPj0gc2VsZi5taW5jb2w6CisJCQkJc2VsZi5zZXRjb2x1bW4obmV3YWJzaW5kZW50KQorCQkJc2VsZi5sYXN0bWF4aW5kZW50ID0gbWF4aW5kZW50CisJCXNlbGYuc2V0dG9wY2VsbCh0b3BjZWxsKQorCQlzZWxmLnNldGRyYXdpbmdtb2RlKDEpCisJCisJZGVmIHVuZm9sZG9iamVjdHMoc2VsZiwgb2JqZWN0cyk6CisJCWZvciBvYmogaW4gb2JqZWN0czoKKwkJCXRyeToKKwkJCQlpbmRleCA9IHNlbGYuaXRlbXMuaW5kZXgob2JqKQorCQkJZXhjZXB0IFZhbHVlRXJyb3I6CisJCQkJcGFzcworCQkJZWxzZToKKwkJCQlzZWxmLmZvbGQoaW5kZXgsIDEpCisJCisJZGVmIGdldHVuZm9sZGVkb2JqZWN0cyhzZWxmKToKKwkJY3VyaW5kZW50ID0gMAorCQlvYmplY3RzID0gW10KKwkJZm9yIGluZGV4IGluIHJhbmdlKGxlbihzZWxmLml0ZW1zKSk6CisJCQkoa2V5LCB2YWx1ZSwgYXJyb3csIGluZGVudCkgPSBzZWxmLml0ZW1zW2luZGV4XQorCQkJaWYgaW5kZW50ID4gY3VyaW5kZW50OgorCQkJCShrLCB2LCBhLCBpKSA9IHNlbGYuaXRlbXNbaW5kZXggLSAxXQorCQkJCW9iamVjdHMuYXBwZW5kKChrLCB2LCAxLCBpKSkKKwkJCQljdXJpbmRlbnQgPSBpbmRlbnQKKwkJCWVsaWYgaW5kZW50IDwgY3VyaW5kZW50OgorCQkJCWN1cmluZGVudCA9IGluZGVudAorCQlyZXR1cm4gb2JqZWN0cworCQorCWRlZiBsaXN0aGl0KHNlbGYsIGlzZGJsKToKKwkJaWYgaXNkYmw6CisJCQlzZWxmLm9wZW5zZWxlY3Rpb24oKQorCQorCWRlZiBvcGVuc2VsZWN0aW9uKHNlbGYpOgorCQlpbXBvcnQgb3MKKwkJc2VsID0gc2VsZi5nZXRzZWxlY3Rpb24oKQorCQlmb3IgaW5kZXggaW4gc2VsOgorCQkJKGtleSwgdmFsdWUsIGFycm93LCBpbmRlbnQpID0gc2VsZltpbmRleF0KKwkJCWlmIGFycm93OgorCQkJCXNlbGYuY2hpbGRyZW4uYXBwZW5kKEJyb3dzZXIodmFsdWUpKQorCQkJZWxpZiB0eXBlKHZhbHVlKSA9PSB0eXBlcy5TdHJpbmdUeXBlIGFuZCAnXDAnIG5vdCBpbiB2YWx1ZToKKwkJCQllZGl0b3IgPSBzZWxmLl9wYXJlbnR3aW5kb3cucGFyZW50LmdldHNjcmlwdCh2YWx1ZSkKKwkJCQlpZiBlZGl0b3I6CisJCQkJCWVkaXRvci5zZWxlY3QoKQorCQkJCQlyZXR1cm4KKwkJCQllbGlmIG9zLnBhdGguZXhpc3RzKHZhbHVlKSBhbmQgb3MucGF0aC5pc2ZpbGUodmFsdWUpOgorCQkJCQlpbXBvcnQgbWFjZnMKKwkJCQkJZnNzID0gbWFjZnMuRlNTcGVjKHZhbHVlKQorCQkJCQlpZiBmc3MuR2V0Q3JlYXRvclR5cGUoKVsxXSA9PSAnVEVYVCc6CisJCQkJCQlXLmdldGFwcGxpY2F0aW9uKCkub3BlbnNjcmlwdCh2YWx1ZSkKKwkKKwlkZWYgaXRlbXJlcHIoc2VsZiwgKGtleSwgdmFsdWUsIGFycm93LCBpbmRlbnQpLCBzdHIgPSBzdHIsIGRvdWJsZV9yZXByID0gZG91YmxlX3JlcHIsIAorCQkJYXJyb3dzID0gYXJyb3dzLCBwYWNrID0gc3RydWN0LnBhY2spOgorCQlhcnJvdyA9IGFycm93c1thcnJvd10KKwkJcmV0dXJuIGFycm93ICsgcGFjaygnaCcsIHNlbGYuaW5kZW50ICogaW5kZW50KSArIHNlbGYuY29sc3RyICsgXAorCQkJCWRvdWJsZV9yZXByKGtleSwgdmFsdWUsIDEpCisJCisJZGVmIGdldG1heGluZGVudChzZWxmLCBtYXggPSBtYXgpOgorCQltYXhpbmRlbnQgPSAwCisJCWZvciBpdGVtIGluIHNlbGYuaXRlbXM6CisJCQltYXhpbmRlbnQgPSBtYXgobWF4aW5kZW50LCBpdGVtWzNdKQorCQlyZXR1cm4gbWF4aW5kZW50CisJCisJZGVmIGRvbWVudV9jb3B5KHNlbGYsICphcmdzKToKKwkJc2VsID0gc2VsZi5nZXRzZWxlY3RlZG9iamVjdHMoKQorCQlzZWxpdGVtcyA9IFtdCisJCWZvciBrZXksIHZhbHVlLCBkdW1teSwgZHVtbXkgaW4gc2VsOgorCQkJc2VsaXRlbXMuYXBwZW5kKGRvdWJsZV9yZXByKGtleSwgdmFsdWUpKQorCQl0ZXh0ID0gc3RyaW5nLmpvaW4oc2VsaXRlbXMsICdccicpCisJCWlmIHRleHQ6CisJCQlpbXBvcnQgU2NyYXAKKwkJCVNjcmFwLlplcm9TY3JhcCgpCisJCQlTY3JhcC5QdXRTY3JhcCgnVEVYVCcsIHRleHQpCisKKworY2xhc3MgQnJvd3NlcjoKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgb2JqZWN0ID0gTm9uZSwgdGl0bGUgPSBOb25lLCBjbG9zZWNoaWxkcmVuID0gMCk6CisJCWlmIGhhc2F0dHIob2JqZWN0LCAnX19uYW1lX18nKToKKwkJCW5hbWUgPSBvYmplY3QuX19uYW1lX18KKwkJZWxzZToKKwkJCW5hbWUgPSAnJworCQlpZiB0aXRsZSBpcyBOb25lOgorCQkJdGl0bGUgPSAnT2JqZWN0IGJyb3dzZXInCisJCQlpZiBuYW1lOgorCQkJCXRpdGxlID0gdGl0bGUgKyAnOiAnICsgbmFtZQorCQlzZWxmLncgPSB3ID0gVy5XaW5kb3coKDMwMCwgNDAwKSwgdGl0bGUsIG1pbnNpemUgPSAoMTAwLCAxMDApKQorCQl3LmluZm8gPSBXLlRleHRCb3goKDE4LCA4LCAtNzAsIDE1KSkKKwkJdy51cGRhdGVidXR0b24gPSBXLkJ1dHRvbigoLTY0LCA0LCA1MCwgMTYpLCAnVXBkYXRlJywgc2VsZi51cGRhdGUpCisJCXcuYnJvd3NlciA9IEJyb3dzZXJXaWRnZXQoKC0xLCAyNCwgMSwgLTE0KSwgTm9uZSkKKwkJdy5iaW5kKCdjbWR1Jywgdy51cGRhdGVidXR0b24ucHVzaCkKKwkJdy5vcGVuKCkKKwkJc2VsZi5zZXQob2JqZWN0LCBuYW1lKQorCQorCWRlZiBjbG9zZShzZWxmKToKKwkJaWYgc2VsZi53LndpZDoKKwkJCXNlbGYudy5jbG9zZSgpCisJCisJZGVmIHNldChzZWxmLCBvYmplY3QsIG5hbWUgPSAnJyk6CisJCVcuU2V0Q3Vyc29yKCd3YXRjaCcpCisJCXRwID0gdHlwZShvYmplY3QpLl9fbmFtZV9fCisJCXRyeToKKwkJCWxlbmd0aCA9IGxlbihvYmplY3QpCisJCWV4Y2VwdDoKKwkJCWxlbmd0aCA9IC0xCisJCWlmIG5vdCBuYW1lIGFuZCBoYXNhdHRyKG9iamVjdCwgJ19fbmFtZV9fJyk6CisJCQluYW1lID0gb2JqZWN0Ll9fbmFtZV9fCisJCWlmIG5hbWU6CisJCQlpbmZvID0gbmFtZSArICc6ICcgKyB0cAorCQllbHNlOgorCQkJaW5mbyA9IHRwCisJCWlmIGxlbmd0aCA+PSAwOgorCQkJaWYgbGVuZ3RoID09IDE6CisJCQkJaW5mbyA9IGluZm8gKyAnICglZCBlbGVtZW50KScgJSBsZW5ndGgKKwkJCWVsc2U6CisJCQkJaW5mbyA9IGluZm8gKyAnICglZCBlbGVtZW50cyknICUgbGVuZ3RoCisJCXNlbGYudy5pbmZvLnNldChpbmZvKQorCQlzZWxmLncuYnJvd3Nlci5zZXQob2JqZWN0KQorCQorCWRlZiB1cGRhdGUoc2VsZik6CisJCXNlbGYudy5icm93c2VyLnVwZGF0ZSgpCisKKworU0lNUExFX1RZUEVTID0gKAorCXR5cGVzLk5vbmVUeXBlLAorCXR5cGVzLkludFR5cGUsCisJdHlwZXMuTG9uZ1R5cGUsCisJdHlwZXMuRmxvYXRUeXBlLAorCXR5cGVzLkNvbXBsZXhUeXBlLAorCXR5cGVzLlN0cmluZ1R5cGUKKykKKworSU5ERVhJTkdfVFlQRVMgPSAoCisJdHlwZXMuVHVwbGVUeXBlLAorCXR5cGVzLkxpc3RUeXBlLAorCXR5cGVzLkRpY3Rpb25hcnlUeXBlCispCisKK2RlZiB1bnBhY2tfb2JqZWN0KG9iamVjdCwgaW5kZW50ID0gMCk6CisJdHAgPSB0eXBlKG9iamVjdCkKKwlpZiB0cCBpbiBTSU1QTEVfVFlQRVMgYW5kIHRwIGlzIG5vdCB0eXBlcy5Ob25lVHlwZToKKwkJcmFpc2UgVHlwZUVycm9yLCAnY2FuuXQgYnJvd3NlIHNpbXBsZSB0eXBlOiAlcycgJSB0cC5fX25hbWVfXworCWVsaWYgdHAgPT0gdHlwZXMuRGljdGlvbmFyeVR5cGU6CisJCXJldHVybiB1bnBhY2tfZGljdChvYmplY3QsIGluZGVudCkKKwllbGlmIHRwIGluICh0eXBlcy5UdXBsZVR5cGUsIHR5cGVzLkxpc3RUeXBlKToKKwkJcmV0dXJuIHVucGFja19zZXF1ZW5jZShvYmplY3QsIGluZGVudCkKKwllbGlmIHRwID09IHR5cGVzLkluc3RhbmNlVHlwZToKKwkJcmV0dXJuIHVucGFja19pbnN0YW5jZShvYmplY3QsIGluZGVudCkKKwllbGlmIHRwID09IHR5cGVzLkNsYXNzVHlwZToKKwkJcmV0dXJuIHVucGFja19jbGFzcyhvYmplY3QsIGluZGVudCkKKwllbGlmIHRwID09IHR5cGVzLk1vZHVsZVR5cGU6CisJCXJldHVybiB1bnBhY2tfZGljdChvYmplY3QuX19kaWN0X18sIGluZGVudCkKKwllbHNlOgorCQlyZXR1cm4gdW5wYWNrX290aGVyKG9iamVjdCwgaW5kZW50KQorCitkZWYgdW5wYWNrX3NlcXVlbmNlKHNlcSwgaW5kZW50ID0gMCk6CisJaXRlbXMgPSBtYXAoTm9uZSwgcmFuZ2UobGVuKHNlcSkpLCBzZXEpCisJaXRlbXMgPSBtYXAobGFtYmRhIChrLCB2KSwgdHlwZSA9IHR5cGUsIHNpbXAgPSBTSU1QTEVfVFlQRVMsIGluZGVudCA9IGluZGVudDogCisJCQkJKGssIHYsIG5vdCB0eXBlKHYpIGluIHNpbXAsIGluZGVudCksIGl0ZW1zKQorCXJldHVybiBpdGVtcworCitkZWYgdW5wYWNrX2RpY3QoZGljdCwgaW5kZW50ID0gMCk6CisJaXRlbXMgPSBkaWN0Lml0ZW1zKCkKKwlyZXR1cm4gcGFja19pdGVtcyhpdGVtcywgaW5kZW50KQorCitkZWYgdW5wYWNrX2luc3RhbmNlKGluc3QsIGluZGVudCA9IDApOgorCWlmIGhhc2F0dHIoaW5zdCwgJ19fcHlicm93c2VfdW5wYWNrX18nKToKKwkJcmV0dXJuIHVucGFja19vYmplY3QoaW5zdC5fX3B5YnJvd3NlX3VucGFja19fKCksIGluZGVudCkKKwllbHNlOgorCQlpdGVtcyA9IFsoJ19fY2xhc3NfXycsIGluc3QuX19jbGFzc19fKV0gKyBpbnN0Ll9fZGljdF9fLml0ZW1zKCkKKwkJcmV0dXJuIHBhY2tfaXRlbXMoaXRlbXMsIGluZGVudCkKKworZGVmIHVucGFja19jbGFzcyhjbHNzLCBpbmRlbnQgPSAwKToKKwlpdGVtcyA9IFsoJ19fYmFzZXNfXycsIGNsc3MuX19iYXNlc19fKSwgKCdfX25hbWVfXycsIGNsc3MuX19uYW1lX18pXSArIGNsc3MuX19kaWN0X18uaXRlbXMoKQorCXJldHVybiBwYWNrX2l0ZW1zKGl0ZW1zLCBpbmRlbnQpCisKK2RlZiB1bnBhY2tfb3RoZXIob2JqZWN0LCBpbmRlbnQgPSAwKToKKwlhdHRycyA9IFtdCisJaWYgaGFzYXR0cihvYmplY3QsICdfX21lbWJlcnNfXycpOgorCQlhdHRycyA9IGF0dHJzICsgb2JqZWN0Ll9fbWVtYmVyc19fCisJaWYgaGFzYXR0cihvYmplY3QsICdfX21ldGhvZHNfXycpOgorCQlhdHRycyA9IGF0dHJzICsgb2JqZWN0Ll9fbWV0aG9kc19fCisJaXRlbXMgPSBbXQorCWZvciBhdHRyIGluIGF0dHJzOgorCQlpdGVtcy5hcHBlbmQoKGF0dHIsIGdldGF0dHIob2JqZWN0LCBhdHRyKSkpCisJcmV0dXJuIHBhY2tfaXRlbXMoaXRlbXMsIGluZGVudCkKKworZGVmIHBhY2tfaXRlbXMoaXRlbXMsIGluZGVudCA9IDApOgorCWl0ZW1zID0gbWFwKGxhbWJkYSAoaywgdiksIHR5cGUgPSB0eXBlLCBzaW1wID0gU0lNUExFX1RZUEVTLCBpbmRlbnQgPSBpbmRlbnQ6IAorCQkJCShrLCB2LCBub3QgdHlwZSh2KSBpbiBzaW1wLCBpbmRlbnQpLCAKKwkJCWl0ZW1zKQorCXJldHVybiB0dXBsZV9jYXNlbGVzc3NvcnQoaXRlbXMpCisKK2RlZiBjYXNlbGVzc3NvcnQoYWxpc3QpOgorCSIiIlJldHVybiBhIHNvcnRlZCBjb3B5IG9mIGEgbGlzdC4gSWYgdGhlcmUgYXJlIG9ubHkgc3RyaW5ncyBpbiB0aGUgbGlzdCwgCisJaXQgd2lsbCBub3QgY29uc2lkZXIgY2FzZSIiIgorCQorCXRyeToKKwkJIyB0dXJuIFsnRk9PJywgICdhYUJjJywgJ0FCY0QnXSBpbnRvIFsoJ2ZvbycsICdGT08nKSwgKCdhYWJjJywgJ2FhQmMnKSwgKCdhYmNkJywgJ0FCY0QnKV0sIGlmIHBvc3NpYmxlCisJCXR1cGxlZGxpc3QgPSBtYXAobGFtYmRhIGl0ZW0sIGxvd2VyID0gc3RyaW5nLmxvd2VyOiAobG93ZXIoaXRlbSksIGl0ZW0pLCBhbGlzdCkKKwlleGNlcHQgVHlwZUVycm9yOgorCQkjIGF0IGxlYXN0IG9uZSBlbGVtZW50IGluIGFsaXN0IGlzIG5vdCBhIHN0cmluZywgcHJvY2VlZCB0aGUgbm9ybWFsIHdheS4uLgorCQlhbGlzdCA9IGFsaXN0WzpdCisJCWFsaXN0LnNvcnQoKQorCQlyZXR1cm4gYWxpc3QKKwllbHNlOgorCQl0dXBsZWRsaXN0LnNvcnQoKQorCQkjIHR1cm4gWygnYWFiYycsICdhYUJjJyksICgnYWJjZCcsICdBQmNEJyksICgnZm9vJywgJ0ZPTycpXSBpbnRvIFsnYWFCYycsICdBQmNEJywgJ0ZPTyddCisJCXJldHVybiBtYXAobGFtYmRhIHg6IHhbMV0sIHR1cGxlZGxpc3QpCisKK2RlZiB0dXBsZV9jYXNlbGVzc3NvcnQoaXRlbXMpOgorCXRyeToKKwkJdHVwbGVkbGlzdCA9IG1hcChsYW1iZGEgdHVwbGUsIGxvd2VyID0gc3RyaW5nLmxvd2VyOiAobG93ZXIodHVwbGVbMF0pLCB0dXBsZSksIGl0ZW1zKQorCWV4Y2VwdCBUeXBlRXJyb3I6CisJCWl0ZW1zID0gaXRlbXNbOl0KKwkJaXRlbXMuc29ydCgpCisJCXJldHVybiBpdGVtcworCWVsc2U6CisJCXR1cGxlZGxpc3Quc29ydCgpCisJCXJldHVybiBtYXAobGFtYmRhIChsb3csIHR1cGxlKTogdHVwbGUsIHR1cGxlZGxpc3QpCisKZGlmZiAtLWdpdCBhL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9QeUNvbnNvbGUucHkgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvUHlDb25zb2xlLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjhjYjJlNGIKLS0tIC9kZXYvbnVsbAorKysgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvUHlDb25zb2xlLnB5CkBAIC0wLDAgKzEsMjkzIEBACitpbXBvcnQgVworaW1wb3J0IEZtCitmcm9tIFdBU1RFY29uc3QgaW1wb3J0ICoKK2Zyb20gU3BlY2lhbEtleXMgaW1wb3J0ICoKK2Zyb20gdHlwZXMgaW1wb3J0ICoKK2ltcG9ydCBFdmVudHMKK2ltcG9ydCBzdHJpbmcKK2ltcG9ydCBzeXMsb3MKK2ltcG9ydCB0cmFjZWJhY2sKK2ltcG9ydCBNYWNPUworaW1wb3J0IE1hY1ByZWZzCitpbXBvcnQgUHlJbnRlcmFjdGl2ZQorCitpZiBub3QgaGFzYXR0cihzeXMsICdwczEnKToKKwlzeXMucHMxID0gJz4+PiAnCitpZiBub3QgaGFzYXR0cihzeXMsICdwczInKToKKwlzeXMucHMyID0gJy4uLiAnCisKKworY2xhc3MgQ29uc29sZVRleHRXaWRnZXQoVy5FZGl0VGV4dCk6CisJCisJZGVmIF9faW5pdF9fKHNlbGYsICphcmdzLCAqKmt3YXJncyk6CisJCWFwcGx5KFcuRWRpdFRleHQuX19pbml0X18sIChzZWxmLCkgKyBhcmdzLCBrd2FyZ3MpCisJCXNlbGYuX2lucHV0c3RhcnQgPSAwCisJCXNlbGYuX2J1ZiA9ICcnCisJCXNlbGYucHlpbnRlcmFjdGl2ZSA9IFB5SW50ZXJhY3RpdmUuUHlJbnRlcmFjdGl2ZSgpCisJCisJCWltcG9ydCBfX21haW5fXworCQlzZWxmLl9uYW1lc3BhY2UgPSBfX21haW5fXy5fX2RpY3RfXworCQorCWRlZiBpbnNlcnQoc2VsZiwgdGV4dCk6CisJCXNlbGYuY2hlY2tzZWxlY3Rpb24oKQorCQlzZWxmLnRlZC5XRUluc2VydCh0ZXh0LCBOb25lLCBOb25lKQorCQlzZWxmLmNoYW5nZWQgPSAxCisJCXNlbGYuc2VsY2hhbmdlZCA9IDEKKwkKKwlkZWYgc2V0X25hbWVzcGFjZShzZWxmLCBkaWN0KToKKwkJaWYgdHlwZShkaWN0KSA8PiBEaWN0aW9uYXJ5VHlwZToKKwkJCXJhaXNlIFR5cGVFcnJvciwgIlRoZSBuYW1lc3BhY2UgbmVlZHMgdG8gYmUgYSBkaWN0aW9uYXJ5IgorCQlzZWxmLl9uYW1lc3BhY2UgPSBkaWN0CisJCisJZGVmIG9wZW4oc2VsZik6CisJCVcuRWRpdFRleHQub3BlbihzZWxmKQorCQlzZWxmLndyaXRlKCdQeXRob24gJyArIHN5cy52ZXJzaW9uICsgJ1xuJyArIHN5cy5jb3B5cmlnaHQgKyAnXG4nKQorCQlzZWxmLndyaXRlKHN5cy5wczEpCisJCXNlbGYuZmx1c2goKQorCQorCWRlZiBrZXkoc2VsZiwgY2hhciwgZXZlbnQpOgorCQkod2hhdCwgbWVzc2FnZSwgd2hlbiwgd2hlcmUsIG1vZGlmaWVycykgPSBldmVudAorCQlpZiBzZWxmLl9lbmFibGVkIGFuZCBub3QgbW9kaWZpZXJzICYgRXZlbnRzLmNtZEtleSBvciBjaGFyIGluIGFycm93a2V5czoKKwkJCWlmIGNoYXIgbm90IGluIG5hdmlnYXRpb25rZXlzOgorCQkJCXNlbGYuY2hlY2tzZWxlY3Rpb24oKQorCQkJaWYgY2hhciA9PSBlbnRlcmtleToKKwkJCQljaGFyID0gcmV0dXJua2V5CisJCQlzZWxzdGFydCwgc2VsZW5kID0gc2VsZi5nZXRzZWxlY3Rpb24oKQorCQkJaWYgY2hhciA9PSBiYWNrc3BhY2VrZXk6CisJCQkJaWYgc2Vsc3RhcnQgPD0gKHNlbGYuX2lucHV0c3RhcnQgLSAoc2Vsc3RhcnQgPD4gc2VsZW5kKSk6CisJCQkJCXJldHVybgorCQkJc2VsZi50ZWQuV0VLZXkob3JkKGNoYXIpLCBtb2RpZmllcnMpCisJCQlpZiBjaGFyIG5vdCBpbiBuYXZpZ2F0aW9ua2V5czoKKwkJCQlzZWxmLmNoYW5nZWQgPSAxCisJCQlpZiBjaGFyIG5vdCBpbiBzY3JvbGxrZXlzOgorCQkJCXNlbGYuc2VsY2hhbmdlZCA9IDEKKwkJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCQlpZiBjaGFyID09IHJldHVybmtleToKKwkJCQl0ZXh0ID0gc2VsZi5nZXQoKVtzZWxmLl9pbnB1dHN0YXJ0OnNlbHN0YXJ0XQorCQkJCXNhdmV5aWVsZCA9IE1hY09TLkVuYWJsZUFwcHN3aXRjaCgwKQorCQkJCXNlbGYucHlpbnRlcmFjdGl2ZS5leGVjdXRlbGluZSh0ZXh0LCBzZWxmLCBzZWxmLl9uYW1lc3BhY2UpCisJCQkJTWFjT1MuRW5hYmxlQXBwc3dpdGNoKHNhdmV5aWVsZCkKKwkJCQlzZWxzdGFydCwgc2VsZW5kID0gc2VsZi5nZXRzZWxlY3Rpb24oKQorCQkJCXNlbGYuX2lucHV0c3RhcnQgPSBzZWxzdGFydAorCQorCWRlZiBkb21lbnVfc2F2ZV9hcyhzZWxmLCAqYXJncyk6CisJCWltcG9ydCBtYWNmcworCQlmc3MsIG9rID0gbWFjZnMuU3RhbmRhcmRQdXRGaWxlKCdTYXZlIGNvbnNvbGUgdGV4dCBhczonLCAnY29uc29sZS50eHQnKQorCQlpZiBub3Qgb2s6CisJCQlyZXR1cm4KKwkJZiA9IG9wZW4oZnNzLmFzX3BhdGhuYW1lKCksICd3YicpCisJCWYud3JpdGUoc2VsZi5nZXQoKSkKKwkJZi5jbG9zZSgpCisJCWZzcy5TZXRDcmVhdG9yVHlwZShXLl9zaWduYXR1cmUsICdURVhUJykKKwkKKwlkZWYgd3JpdGUoc2VsZiwgdGV4dCk6CisJCXNlbGYuX2J1ZiA9IHNlbGYuX2J1ZiArIHRleHQKKwkJaWYgJ1xuJyBpbiBzZWxmLl9idWY6CisJCQlzZWxmLmZsdXNoKCkKKwkKKwlkZWYgZmx1c2goc2VsZik6CisJCXN0dWZmID0gc3RyaW5nLnNwbGl0KHNlbGYuX2J1ZiwgJ1xuJykKKwkJc3R1ZmYgPSBzdHJpbmcuam9pbihzdHVmZiwgJ1xyJykKKwkJc2VsZi5zZXRzZWxlY3Rpb25fYXRfZW5kKCkKKwkJc2VsZi50ZWQuV0VJbnNlcnQoc3R1ZmYsIE5vbmUsIE5vbmUpCisJCXNlbHN0YXJ0LCBzZWxlbmQgPSBzZWxmLmdldHNlbGVjdGlvbigpCisJCXNlbGYuX2lucHV0c3RhcnQgPSBzZWxzdGFydAorCQlzZWxmLl9idWYgPSAiIgorCQlzZWxmLnRlZC5XRUNsZWFyVW5kbygpCisJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCisJZGVmIHNlbGVjdGlvbl9vayhzZWxmKToKKwkJc2Vsc3RhcnQsIHNlbGVuZCA9IHNlbGYuZ2V0c2VsZWN0aW9uKCkKKwkJcmV0dXJuIG5vdCAoc2Vsc3RhcnQgPCBzZWxmLl9pbnB1dHN0YXJ0IG9yIHNlbGVuZCA8IHNlbGYuX2lucHV0c3RhcnQpCisJCisJZGVmIGNoZWNrc2VsZWN0aW9uKHNlbGYpOgorCQlpZiBub3Qgc2VsZi5zZWxlY3Rpb25fb2soKToKKwkJCXNlbGYuc2V0c2VsZWN0aW9uX2F0X2VuZCgpCisJCisJZGVmIHNldHNlbGVjdGlvbl9hdF9lbmQoc2VsZik6CisJCWVuZCA9IHNlbGYudGVkLldFR2V0VGV4dExlbmd0aCgpCisJCXNlbGYuc2V0c2VsZWN0aW9uKGVuZCwgZW5kKQorCQlzZWxmLnVwZGF0ZXNjcm9sbGJhcnMoKQorCQkKKwlkZWYgZG9tZW51X2N1dChzZWxmLCAqYXJncyk6CisJCWlmIG5vdCBzZWxmLnNlbGVjdGlvbl9vaygpOgorCQkJcmV0dXJuCisJCVcuRWRpdFRleHQuZG9tZW51X2N1dChzZWxmKQorCQorCWRlZiBkb21lbnVfcGFzdGUoc2VsZiwgKmFyZ3MpOgorCQlpZiBub3Qgc2VsZi5zZWxlY3Rpb25fb2soKToKKwkJCXNlbGYuc2V0c2VsZWN0aW9uX2F0X2VuZCgpCisJCVcuRWRpdFRleHQuZG9tZW51X3Bhc3RlKHNlbGYpCisJCisJZGVmIGRvbWVudV9jbGVhcihzZWxmLCAqYXJncyk6CisJCWlmIG5vdCBzZWxmLnNlbGVjdGlvbl9vaygpOgorCQkJcmV0dXJuCisJCVcuRWRpdFRleHQuZG9tZW51X2NsZWFyKHNlbGYpCisKKworY2xhc3MgUHlDb25zb2xlKFcuV2luZG93KToKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgYm91bmRzLCBzaG93ID0gMSwgZm9udHNldHRpbmdzID0gKCJNb25hY28iLCAwLCA5LCAoMCwgMCwgMCkpLCB1bmNsb3NhYmxlID0gMCk6CisJCVcuV2luZG93Ll9faW5pdF9fKHNlbGYsCisJCQkJCWJvdW5kcywgCisJCQkJCSJQeXRob24gSW50ZXJhY3RpdmUiLCAKKwkJCQkJbWluc2l6ZSA9ICgyMDAsIDEwMCksIAorCQkJCQl0YWJiYWJsZSA9IDAsIAorCQkJCQlzaG93ID0gc2hvdykKKwkJCisJCXNlbGYuX3VuY2xvc2FibGUgPSB1bmNsb3NhYmxlCisJCWNvbnNvbGV0ZXh0ID0gQ29uc29sZVRleHRXaWRnZXQoKC0xLCAtMSwgLTE0LCAxKSwgaW5zZXQgPSAoNiwgNSksIGZvbnRzZXR0aW5ncyA9IGZvbnRzZXR0aW5ncykKKwkJc2VsZi5fYmFyeSA9IFcuU2Nyb2xsYmFyKCgtMTUsIDE0LCAxNiwgLTE0KSwgY29uc29sZXRleHQudnNjcm9sbCwgbWF4ID0gMzI3NjcpCisJCXNlbGYuY29uc29sZXRleHQgPSBjb25zb2xldGV4dAorCQlzZWxmLm5hbWVzcGFjZW1lbnUgPSBXLlBvcHVwTWVudSgoLTE1LCAtMSwgMTYsIDE2KSwgW10sIHNlbGYuY29uc29sZXRleHQuc2V0X25hbWVzcGFjZSkKKwkJc2VsZi5uYW1lc3BhY2VtZW51LmJpbmQoJzxjbGljaz4nLCBzZWxmLm1ha2VuYW1lc3BhY2VtZW51KQorCQlzZWxmLm9wZW4oKQorCQorCWRlZiBtYWtlbmFtZXNwYWNlbWVudShzZWxmLCAqYXJncyk6CisJCVcuU2V0Q3Vyc29yKCd3YXRjaCcpCisJCW5hbWVzcGFjZWxpc3QgPSBzZWxmLmdldG5hbWVzcGFjZWxpc3QoKQorCQlzZWxmLm5hbWVzcGFjZW1lbnUuc2V0KFsoIkZvbnQgc2V0dGluZ3OKIiwgc2VsZi5kb2ZvbnRzZXR0aW5ncyksIAorCQkJCVsiTmFtZXNwYWNlIl0gKyBuYW1lc3BhY2VsaXN0LCAoIkNsZWFyIGJ1ZmZlciIsIHNlbGYuY2xlYXJidWZmZXIpLCAoIkJyb3dzZSBuYW1lc3BhY2WKIiwgc2VsZi5icm93c2VuYW1lc3BhY2UpXSkKKwkJY3VycmVudG5hbWUgPSBzZWxmLmNvbnNvbGV0ZXh0Ll9uYW1lc3BhY2VbIl9fbmFtZV9fIl0KKwkJZm9yIGkgaW4gcmFuZ2UobGVuKG5hbWVzcGFjZWxpc3QpKToKKwkJCWlmIG5hbWVzcGFjZWxpc3RbaV1bMF0gPT0gY3VycmVudG5hbWU6CisJCQkJYnJlYWsKKwkJZWxzZToKKwkJCXJldHVybgorCQkjIFhYWCB0aGlzIGZ1bmN0aW9uYWxpdHkgc2hvdWxkIGJlIGdlbmVyYWxseSBhdmFpbGFibGUgaW4gV21lbnVzCisJCXN1Ym1lbnVpZCA9IHNlbGYubmFtZXNwYWNlbWVudS5tZW51Lm1lbnUuR2V0SXRlbU1hcmsoMikKKwkJbWVudSA9IHNlbGYubmFtZXNwYWNlbWVudS5tZW51LmJhci5tZW51c1tzdWJtZW51aWRdCisJCW1lbnUubWVudS5DaGVja0l0ZW0oaSArIDEsIDEpCisJCisJZGVmIGJyb3dzZW5hbWVzcGFjZShzZWxmKToKKwkJaW1wb3J0IFB5QnJvd3NlciwgVworCQlXLlNldEN1cnNvcignd2F0Y2gnKQorCQlQeUJyb3dzZXIuQnJvd3NlcihzZWxmLmNvbnNvbGV0ZXh0Ll9uYW1lc3BhY2UsIHNlbGYuY29uc29sZXRleHQuX25hbWVzcGFjZVsiX19uYW1lX18iXSkKKwkKKwlkZWYgY2xlYXJidWZmZXIoc2VsZik6CisJCWltcG9ydCBSZXMKKwkJc2VsZi5jb25zb2xldGV4dC50ZWQuV0VVc2VUZXh0KFJlcy5SZXNvdXJjZSgnJykpCisJCXNlbGYuY29uc29sZXRleHQud3JpdGUoc3lzLnBzMSkKKwkJc2VsZi5jb25zb2xldGV4dC5mbHVzaCgpCisJCisJZGVmIGdldG5hbWVzcGFjZWxpc3Qoc2VsZik6CisJCWltcG9ydCBfX21haW5fXworCQllZGl0b3JzID0gZmlsdGVyKGxhbWJkYSB4OiB4Ll9fY2xhc3NfXy5fX25hbWVfXyA9PSAiRWRpdG9yIiwgc2VsZi5wYXJlbnQuX3dpbmRvd3MudmFsdWVzKCkpCisJCQorCQluYW1lc3BhY2VzID0gWyAoIl9fbWFpbl9fIixfX21haW5fXy5fX2RpY3RfXykgXQorCQlmb3IgZWQgaW4gZWRpdG9yczoKKwkJCW1vZG5hbWUgPSBvcy5wYXRoLnNwbGl0ZXh0KGVkLnRpdGxlKVswXQorCQkJaWYgc3lzLm1vZHVsZXMuaGFzX2tleShtb2RuYW1lKToKKwkJCQltb2R1bGUgPSBzeXMubW9kdWxlc1ttb2RuYW1lXSAKKwkJCQluYW1lc3BhY2VzLmFwcGVuZCgobW9kbmFtZSwgbW9kdWxlLl9fZGljdF9fKSkKKwkJCWVsc2U6CisJCQkJaWYgZWQudGl0bGVbLTM6XSA9PSAnLnB5JzoKKwkJCQkJbW9kbmFtZSA9IGVkLnRpdGxlWzotM10KKwkJCQllbHNlOgorCQkJCQltb2RuYW1lID0gZWQudGl0bGUKKwkJCQllZC5nbG9iYWxzWyJfX25hbWVfXyJdID0gbW9kbmFtZQorCQkJCW5hbWVzcGFjZXMuYXBwZW5kKChtb2RuYW1lLCBlZC5nbG9iYWxzKSkKKwkJcmV0dXJuIG5hbWVzcGFjZXMKKwkKKwlkZWYgZG9mb250c2V0dGluZ3Moc2VsZik6CisJCWltcG9ydCBGb250U2V0dGluZ3MKKwkJZm9udHNldHRpbmdzID0gRm9udFNldHRpbmdzLkZvbnREaWFsb2coc2VsZi5jb25zb2xldGV4dC5nZXRmb250c2V0dGluZ3MoKSkKKwkJaWYgZm9udHNldHRpbmdzOgorCQkJc2VsZi5jb25zb2xldGV4dC5zZXRmb250c2V0dGluZ3MoZm9udHNldHRpbmdzKQorCQorCWRlZiBzaG93KHNlbGYsIG9ub2ZmID0gMSk6CisJCVcuV2luZG93LnNob3coc2VsZiwgb25vZmYpCisJCWlmIG9ub2ZmOgorCQkJc2VsZi5zZWxlY3QoKQorCQorCWRlZiBjbG9zZShzZWxmKToKKwkJaWYgc2VsZi5fdW5jbG9zYWJsZToKKwkJCXNlbGYuc2hvdygwKQorCQkJcmV0dXJuIC0xCisJCVcuV2luZG93LmNsb3NlKHNlbGYpCisJCisJZGVmIHdyaXRlcHJlZnMoc2VsZik6CisJCXByZWZzID0gTWFjUHJlZnMuR2V0UHJlZnMoVy5nZXRhcHBsaWNhdGlvbigpLnByZWZmaWxlcGF0aCkKKwkJcHJlZnMuY29uc29sZS5zaG93ID0gc2VsZi5pc3Zpc2libGUoKQorCQlwcmVmcy5jb25zb2xlLndpbmRvd2JvdW5kcyA9IHNlbGYuZ2V0Ym91bmRzKCkKKwkJcHJlZnMuY29uc29sZS5mb250c2V0dGluZ3MgPSBzZWxmLmNvbnNvbGV0ZXh0LmdldGZvbnRzZXR0aW5ncygpCisJCXByZWZzLnNhdmUoKQorCisKK2NsYXNzIE91dHB1dFRleHRXaWRnZXQoVy5FZGl0VGV4dCk6CisJCisJZGVmIF9nZXRmbGFncyhzZWxmKToKKwkJaW1wb3J0IFdBU1RFY29uc3QKKwkJcmV0dXJuIFdBU1RFY29uc3Qud2VEb0F1dG9TY3JvbGwgfCBXQVNURWNvbnN0LndlRG9Nb25vU3R5bGVkIHwgXAorCQkJCVdBU1RFY29uc3Qud2VEb1VuZG8KKworY2xhc3MgUHlPdXRwdXQ6CisJCisJZGVmIF9faW5pdF9fKHNlbGYpOgorCQlzZWxmLncgPSBOb25lCisJCXNlbGYuY2xvc2VkID0gMQorCQlzZWxmLl9idWYgPSAnJworCQkjIHNob3VsZCBiZSBhYmxlIHRvIHNldCB0aGlzCisJCXNlbGYuc2F2ZXN0ZG91dCwgc2VsZi5zYXZlc3RkZXJyID0gc3lzLnN0ZG91dCwgc3lzLnN0ZGVycgorCQlzeXMuc3RkZXJyID0gc3lzLnN0ZG91dCA9IHNlbGYKKwkKKwlkZWYgd3JpdGUoc2VsZiwgdGV4dCk6CisJCXNlbGYuX2J1ZiA9IHNlbGYuX2J1ZiArIHRleHQKKwkJaWYgJ1xuJyBpbiBzZWxmLl9idWY6CisJCQlzZWxmLmZsdXNoKCkKKwkKKwlkZWYgZmx1c2goc2VsZik6CisJCXNlbGYuc2hvdygpCisJCXN0dWZmID0gc3RyaW5nLnNwbGl0KHNlbGYuX2J1ZiwgJ1xuJykKKwkJc3R1ZmYgPSBzdHJpbmcuam9pbihzdHVmZiwgJ1xyJykKKwkJZW5kID0gc2VsZi53Lm91dHB1dHRleHQudGVkLldFR2V0VGV4dExlbmd0aCgpCisJCXNlbGYudy5vdXRwdXR0ZXh0LnNldHNlbGVjdGlvbihlbmQsIGVuZCkKKwkJc2VsZi53Lm91dHB1dHRleHQudGVkLldFSW5zZXJ0KHN0dWZmLCBOb25lLCBOb25lKQorCQlzZWxmLl9idWYgPSAiIgorCQlzZWxmLncub3V0cHV0dGV4dC50ZWQuV0VDbGVhclVuZG8oKQorCQlzZWxmLncub3V0cHV0dGV4dC51cGRhdGVzY3JvbGxiYXJzKCkKKwkKKwlkZWYgc2hvdyhzZWxmKToKKwkJaWYgc2VsZi5jbG9zZWQ6CisJCQlpZiBub3Qgc2VsZi53OgorCQkJCXNlbGYuc2V0dXB3aWRnZXRzKCkKKwkJCQlzZWxmLncub3BlbigpCisJCQkJc2VsZi5jbG9zZWQgPSAwCisJCQllbHNlOgorCQkJCXNlbGYudy5zaG93KDEpCisJCQkJc2VsZi5jbG9zZWQgPSAwCisJCQkJc2VsZi53LnNlbGVjdCgpCisJCisJZGVmIHNldHVwd2lkZ2V0cyhzZWxmKTogCisJCXNlbGYudyA9IFcuV2luZG93KCg0NTAsIDIwMCksICJPdXRwdXQiLCBtaW5zaXplID0gKDIwMCwgMTAwKSwgdGFiYmFibGUgPSAwKQorCQlzZWxmLncub3V0cHV0dGV4dCA9IE91dHB1dFRleHRXaWRnZXQoKC0xLCAtMSwgLTE0LCAxKSwgaW5zZXQgPSAoNiwgNSkpCisJCXNlbGYudy5fYmFyeSA9IFcuU2Nyb2xsYmFyKCgtMTUsIC0xLCAxNiwgLTE0KSwgc2VsZi53Lm91dHB1dHRleHQudnNjcm9sbCwgbWF4ID0gMzI3NjcpCisJCXNlbGYudy5iaW5kKCI8Y2xvc2U+Iiwgc2VsZi5jbG9zZSkKKwkJc2VsZi53LmJpbmQoIjxhY3RpdmF0ZT4iLCBzZWxmLmFjdGl2YXRlKQorCQorCWRlZiBhY3RpdmF0ZShzZWxmLCBvbm9mZik6CisJCWlmIG9ub2ZmOgorCQkJc2VsZi5jbG9zZWQgPSAwCisJCisJZGVmIGNsb3NlKHNlbGYpOgorCQlzZWxmLncuc2hvdygwKQorCQlzZWxmLmNsb3NlZCA9IDEKKwkJcmV0dXJuIC0xCisKKworZGVmIGluc3RhbGxjb25zb2xlKGRlZmF1bHRzaG93ID0gMSk6CisJZ2xvYmFsIGNvbnNvbGUKKwlwcmVmcyA9IE1hY1ByZWZzLkdldFByZWZzKFcuZ2V0YXBwbGljYXRpb24oKS5wcmVmZmlsZXBhdGgpCisJaWYgbm90IHByZWZzLmNvbnNvbGUgb3Igbm90IGhhc2F0dHIocHJlZnMuY29uc29sZSwgJ3Nob3cnKToKKwkJcHJlZnMuY29uc29sZS5zaG93ID0gZGVmYXVsdHNob3cKKwlpZiBub3QgaGFzYXR0cihwcmVmcy5jb25zb2xlLCAid2luZG93Ym91bmRzIik6CisJCXByZWZzLmNvbnNvbGUud2luZG93Ym91bmRzID0gKDQ1MCwgMjUwKQorCWlmIG5vdCBoYXNhdHRyKHByZWZzLmNvbnNvbGUsICJmb250c2V0dGluZ3MiKToKKwkJcHJlZnMuY29uc29sZS5mb250c2V0dGluZ3MgPSAoIk1vbmFjbyIsIDAsIDksICgwLCAwLCAwKSkKKwljb25zb2xlID0gUHlDb25zb2xlKHByZWZzLmNvbnNvbGUud2luZG93Ym91bmRzLCBwcmVmcy5jb25zb2xlLnNob3csIHByZWZzLmNvbnNvbGUuZm9udHNldHRpbmdzLCAxKQorCitkZWYgaW5zdGFsbG91dHB1dCgpOgorCWdsb2JhbCBvdXRwdXQKKwlvdXRwdXQgPSBQeU91dHB1dCgpCisKKwpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1B5RGVidWdnZXIucHkgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvUHlEZWJ1Z2dlci5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jMWY1Y2UwCi0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1B5RGVidWdnZXIucHkKQEAgLTAsMCArMSw4ODAgQEAKK2ltcG9ydCBzeXMKK2ltcG9ydCBiZGIKK2ltcG9ydCB0eXBlcworaW1wb3J0IG9zCisKK2ltcG9ydCBXCitpbXBvcnQgV0FTVEVjb25zdAoraW1wb3J0IFB5QnJvd3NlcgoraW1wb3J0IFFkCitpbXBvcnQgRXZ0CitpbXBvcnQgTGlzdHMKK2ltcG9ydCBNYWNPUworX2ZpbGVuYW1lcyA9IHt9CisKK1NJTVBMRV9UWVBFUyA9ICgKKwl0eXBlcy5Ob25lVHlwZSwKKwl0eXBlcy5JbnRUeXBlLAorCXR5cGVzLkxvbmdUeXBlLAorCXR5cGVzLkZsb2F0VHlwZSwKKwl0eXBlcy5Db21wbGV4VHlwZSwKKwl0eXBlcy5TdHJpbmdUeXBlCispCisKKworY2xhc3MgRGVidWdnZXIoYmRiLkJkYik6CisJCisJZGVmIF9faW5pdF9fKHNlbGYsIHRpdGxlID0gJ0RlYnVnZ2VyJyk6CisJCWJkYi5CZGIuX19pbml0X18oc2VsZikKKwkJc2VsZi5jbG9zZWQgPSAxCisJCXNlbGYudGl0bGUgPSB0aXRsZQorCQlzZWxmLmJyZWFrc3ZpZXdlciA9IE5vbmUKKwkJc2VsZi5yZXNldCgpCisJCXNlbGYudHJhY2luZyA9IDAKKwkJc2VsZi50cmFjaW5nbW9uaXRvcnRpbWUgPSBFdnQuVGlja0NvdW50KCkKKwkJCisJCXByZWZzID0gVy5nZXRhcHBsaWNhdGlvbigpLmdldHByZWZzKCkKKwkJaWYgcHJlZnMuZGVidWdnZXI6CisJCQlzZWxmLmJyZWFrcyA9IHByZWZzLmRlYnVnZ2VyLmJyZWFrcworCQkJc2VsZi5ib3VuZHMsIHNlbGYuaG9ycGFuZXMsIHNlbGYudmVycGFuZXMgPSBwcmVmcy5kZWJ1Z2dlci53aW5kb3dzZXR0aW5ncworCQkJc2VsZi50cmFjZW1hZ2ljID0gcHJlZnMuZGVidWdnZXIudHJhY2VtYWdpYworCQkJZm9yIGtleSBpbiBzZWxmLmJyZWFrcy5rZXlzKCk6CisJCQkJaWYga2V5WzoxXSA9PSAnPCcgYW5kIGtleVstMTpdID09ICc+JzoKKwkJCQkJZGVsIHNlbGYuYnJlYWtzW2tleV0KKwkJZWxzZToKKwkJCXNlbGYuYnJlYWtzID0ge30KKwkJCXNlbGYuaG9ycGFuZXMgPSAoMC40LCAwLjYpCisJCQlzZWxmLnZlcnBhbmVzID0gKDAuMywgMC4zNSwgMC4zNSkKKwkJCXNlbGYuYm91bmRzID0gKDYwMCwgNDAwKQorCQkJc2VsZi50cmFjZW1hZ2ljID0gMAorCQlzZWxmLmxhc3RzdGFja3NlbCA9IE5vbmUKKwkJc2VsZi5lZGl0b3JzID0ge30KKwkKKwlkZWYgcmVzZXQoc2VsZik6CisJCXNlbGYuY3VycmVudGZyYW1lID0gTm9uZQorCQlzZWxmLmZpbGUgPSBOb25lCisJCXNlbGYubGFzdHN0YWNrID0gTm9uZQorCQlzZWxmLnJlYXNvbiA9ICdOb3QgcnVubmluZycKKwkJc2VsZi5jb250aW51ZXdpdGhvdXRkZWJ1Z2dlciA9IDAKKwkJYmRiLkJkYi5yZXNldChzZWxmKQorCQlzZWxmLmZvcmdldCgpCisJCisJZGVmIHN0YXJ0KHNlbGYsIGJvdHRvbWZyYW1lID0gTm9uZSwgcnVubmluZyA9IDApOgorCQlXLmdldGFwcGxpY2F0aW9uKCkuRGVidWdnZXJRdWl0ID0gYmRiLkJkYlF1aXQKKwkJaW1wb3J0IE1lbnUKKwkJTWVudS5IaWxpdGVNZW51KDApCisJCWlmIHNlbGYuY2xvc2VkOgorCQkJc2VsZi5zZXR1cHdpZGdldHMoc2VsZi50aXRsZSkKKwkJCXNlbGYuY2xvc2VkID0gMAorCQlpZiBub3Qgc2VsZi53LnBhcmVudC5kZWJ1Z2dlcl9xdWl0dGluZzoKKwkJCXNlbGYudy5zZWxlY3QoKQorCQkJcmFpc2UgVy5BbGVydEVycm9yLCAnVGhlcmUgaXMgYW5vdGhlciBkZWJ1Z2dlciBzZXNzaW9uIGJ1c3kuJworCQlzZWxmLnJlc2V0KCkKKwkJc2VsZi5ib3RmcmFtZSA9IGJvdHRvbWZyYW1lCisJCWlmIHJ1bm5pbmc6CisJCQlzZWxmLnNldF9jb250aW51ZSgpCisJCQlzZWxmLnJlYXNvbiA9ICdSdW5uaW5niicKKwkJCXNlbGYuc2V0c3RhdGUoJ3J1bm5pbmcnKQorCQllbHNlOgorCQkJc2VsZi5zZXRfc3RlcCgpCisJCQlzZWxmLnJlYXNvbiA9ICdzdG9wcGVkJworCQkJc2VsZi5zZXRzdGF0ZSgnc3RvcHBlZCcpCisJCXN5cy5zZXR0cmFjZShzZWxmLnRyYWNlX2Rpc3BhdGNoKQorCQorCWRlZiBzdG9wKHNlbGYpOgorCQlzZWxmLnNldF9xdWl0KCkKKwkJaWYgc2VsZi53LnBhcmVudDoKKwkJCXNlbGYuZXhpdF9tYWlubG9vcCgpCisJCQlzZWxmLnJlc2V0d2lkZ2V0cygpCisJCisJZGVmIHNldF9jb250aW51ZV93aXRob3V0X2RlYnVnZ2VyKHNlbGYpOgorCQlzeXMuc2V0dHJhY2UoTm9uZSkKKwkJc2VsZi5zZXRfcXVpdCgpCisJCXNlbGYuY2xlYXJfdHJhY2VmdW5jcygpCisJCXNlbGYuY29udGludWV3aXRob3V0ZGVidWdnZXIgPSAxCisJCWlmIHNlbGYudy5wYXJlbnQ6CisJCQlzZWxmLmV4aXRfbWFpbmxvb3AoKQorCQkJc2VsZi5yZXNldHdpZGdldHMoKQorCQorCWRlZiBjbGVhcl90cmFjZWZ1bmNzKHNlbGYpOgorCQl0cnk6CisJCQlyYWlzZSAnc3BhbScKKwkJZXhjZXB0OgorCQkJcGFzcworCQlmcmFtZSA9IHN5cy5leGNfdHJhY2ViYWNrLnRiX2ZyYW1lCisJCXdoaWxlIGZyYW1lIGlzIG5vdCBOb25lOgorCQkJZGVsIGZyYW1lLmZfdHJhY2UKKwkJCWZyYW1lID0gZnJhbWUuZl9iYWNrCisJCisJZGVmIHBvc3Rtb3J0ZW0oc2VsZiwgZXhjX3R5cGUsIGV4Y192YWx1ZSwgdHJhY2ViYWNrKToKKwkJaWYgc2VsZi5jbG9zZWQ6CisJCQlzZWxmLnNldHVwd2lkZ2V0cyhzZWxmLnRpdGxlKQorCQkJc2VsZi5jbG9zZWQgPSAwCisJCWlmIG5vdCBzZWxmLncucGFyZW50LmRlYnVnZ2VyX3F1aXR0aW5nOgorCQkJcmFpc2UgVy5BbGVydEVycm9yLCAnVGhlcmUgaXMgYW5vdGhlciBkZWJ1Z2dlciBzZXNzaW9uIGJ1c3kuJworCQlzZWxmLnJlc2V0KCkKKwkJaWYgdHJhY2ViYWNrOgorCQkJc2VsZi5ib3RmcmFtZSA9IHRyYWNlYmFjay50Yl9mcmFtZQorCQkJd2hpbGUgdHJhY2ViYWNrLnRiX25leHQgPD4gTm9uZToKKwkJCQl0cmFjZWJhY2sgPSB0cmFjZWJhY2sudGJfbmV4dAorCQkJZnJhbWUgPSB0cmFjZWJhY2sudGJfZnJhbWUKKwkJZWxzZToKKwkJCXNlbGYuYm90ZnJhbWUgPSBOb25lCisJCQlmcmFtZSA9IE5vbmUKKwkJc2VsZi53LnBhbmVzLmJvdHRvbS5idXR0b25zLmtpbGxidXR0b24uZW5hYmxlKDEpCisJCXNlbGYucmVhc29uID0gJyhkZWFkKSAnICsgc2VsZi5mb3JtYXRleGNlcHRpb24oZXhjX3R5cGUsIGV4Y192YWx1ZSkKKwkJc2VsZi53LnNlbGVjdCgpCisJCXNlbGYuc2V0dXAoZnJhbWUsIHRyYWNlYmFjaykKKwkJc2VsZi5zZXRzdGF0ZSgnZGVhZCcpCisJCXNlbGYuc2hvd3N0YWNrKHNlbGYuY3VyaW5kZXgpCisJCXNlbGYuc2hvd2ZyYW1lKHNlbGYuY3VyaW5kZXgpCisJCisJZGVmIHNldHVwd2lkZ2V0cyhzZWxmLCB0aXRsZSk6CisJCXNlbGYudyA9IHcgPSBXLldpbmRvdyhzZWxmLmJvdW5kcywgdGl0bGUsIG1pbnNpemUgPSAoNTAwLCAzMDApKQorCQkKKwkJdy5wYW5lcyA9IFcuSG9yaXpvbnRhbFBhbmVzKCg4LCA0LCAtOCwgLTgpLCBzZWxmLmhvcnBhbmVzKQorCQkKKwkJdy5wYW5lcy5icm93c2VycGFuZXMgPSBicm93c2VycGFuZXMgPSBXLlZlcnRpY2FsUGFuZXMoTm9uZSwgc2VsZi52ZXJwYW5lcykKKwkJCisJCWJyb3dzZXJwYW5lcy5zdGFja2xpc3QgPSBXLkdyb3VwKE5vbmUpCisJCWJyb3dzZXJwYW5lcy5zdGFja2xpc3QudGl0bGUgPSBXLlRleHRCb3goKDQsIDAsIDAsIDEyKSwgJ1N0YWNrJykKKwkJYnJvd3NlcnBhbmVzLnN0YWNrbGlzdC5zdGFjayA9IFcuTGlzdCgoMCwgMTYsIDAsIDApLCBjYWxsYmFjayA9IHNlbGYuZG9fc3RhY2ssIGZsYWdzID0gTGlzdHMubE9ubHlPbmUpCisJCQorCQlicm93c2VycGFuZXMubG9jYWxzID0gVy5Hcm91cChOb25lKQorCQlicm93c2VycGFuZXMubG9jYWxzLnRpdGxlID0gVy5UZXh0Qm94KCg0LCAwLCAwLCAxMiksICdMb2NhbCB2YXJpYWJsZXMnKQorCQlicm93c2VycGFuZXMubG9jYWxzLmJyb3dzZXIgPSBQeUJyb3dzZXIuQnJvd3NlcldpZGdldCgoMCwgMTYsIDAsIDApKQorCQkKKwkJYnJvd3NlcnBhbmVzLmdsb2JhbHMgPSBXLkdyb3VwKE5vbmUpCisJCWJyb3dzZXJwYW5lcy5nbG9iYWxzLnRpdGxlID0gVy5UZXh0Qm94KCg0LCAwLCAwLCAxMiksICdHbG9iYWwgdmFyaWFibGVzJykKKwkJYnJvd3NlcnBhbmVzLmdsb2JhbHMuYnJvd3NlciA9IFB5QnJvd3Nlci5Ccm93c2VyV2lkZ2V0KCgwLCAxNiwgMCwgMCkpCisJCQorCQl3LnBhbmVzLmJvdHRvbSA9IGJvdHRvbSA9IFcuR3JvdXAoTm9uZSkKKwkJYm90dG9tLnNyYyA9IHNyYyA9IFcuR3JvdXAoKDAsIDUyLCAwLCAwKSkKKwkJc291cmNlID0gU291cmNlVmlld2VyKCgxLCAxLCAtMTUsIC0xNSksIHJlYWRvbmx5ID0gMSwgZGVidWdnZXIgPSBzZWxmKQorCQlzcmMub3B0aW9uc21lbnUgPSBXLlBvcHVwTWVudSgoLTE2LCAwLCAxNiwgMTYpLCBbXSkKKwkJc3JjLm9wdGlvbnNtZW51LmJpbmQoJzxjbGljaz4nLCBzZWxmLm1ha2VvcHRpb25zbWVudSkKKwkJCisJCXNyYy5fYmFyeCA9IFcuU2Nyb2xsYmFyKCgwLCAtMTYsIC0xNSwgMTYpLCBzb3VyY2UuaHNjcm9sbCwgbWF4ID0gMzI3NjcpCisJCXNyYy5fYmFyeSA9IFcuU2Nyb2xsYmFyKCgtMTYsIDE1LCAxNiwgLTE1KSwgc291cmNlLnZzY3JvbGwsIG1heCA9IDMyNzY3KQorCQlzcmMuc291cmNlID0gc291cmNlCisJCXNyYy5mcmFtZSA9IFcuRnJhbWUoKDAsIDAsIC0xNSwgLTE1KSkKKwkJCisJCWJvdHRvbS50cmFjaW5nbW9uaXRvciA9IFRyYWNpbmdNb25pdG9yKCgwLCAyMywgNiwgNikpCisJCWJvdHRvbS5zdGF0ZSA9IFcuVGV4dEJveCgoMTIsIDIwLCAwLCAxNiksIHNlbGYucmVhc29uKQorCQkKKwkJYm90dG9tLnNyY3RpdGxlID0gVy5UZXh0Qm94KCgxMiwgMzYsIDAsIDE0KSkKKwkJYm90dG9tLmJ1dHRvbnMgPSBidXR0b25zID0gVy5Hcm91cCgoMTIsIDAsIDAsIDE2KSkKKwkJCisJCWJ1dHRvbnMucnVuYnV0dG9uID0gVy5CdXR0b24oKDAsIDAsIDUwLCAxNiksICJSdW4iLCBzZWxmLmRvX3J1bikKKwkJYnV0dG9ucy5zdG9wYnV0dG9uID0gVy5CdXR0b24oKDU4LCAwLCA1MCwgMTYpLCAiU3RvcCIsIHNlbGYuZG9fc3RvcCkKKwkJYnV0dG9ucy5raWxsYnV0dG9uID0gVy5CdXR0b24oKDExNiwgMCwgNTAsIDE2KSwgIktpbGwiLCBzZWxmLmRvX2tpbGwpCisJCWJ1dHRvbnMubGluZSA9IFcuVmVydGljYWxMaW5lKCgxNzMsIDAsIDAsIDApKQorCQlidXR0b25zLnN0ZXBidXR0b24gPSBXLkJ1dHRvbigoMTgxLCAwLCA1MCwgMTYpLCAiU3RlcCIsIHNlbGYuZG9fc3RlcCkKKwkJYnV0dG9ucy5zdGVwaW5idXR0b24gPSBXLkJ1dHRvbigoMjM5LCAwLCA1MCwgMTYpLCAiU3RlcCBpbiIsIHNlbGYuZG9fc3RlcGluKQorCQlidXR0b25zLnN0ZXBvdXRidXR0b24gPSBXLkJ1dHRvbigoMjk3LCAwLCA1MCwgMTYpLCAiU3RlcCBvdXQiLCBzZWxmLmRvX3N0ZXBvdXQpCisJCQorCQl3LmJpbmQoJ2NtZHInLCBidXR0b25zLnJ1bmJ1dHRvbi5wdXNoKQorCQl3LmJpbmQoJ2NtZC4nLCBidXR0b25zLnN0b3BidXR0b24ucHVzaCkKKwkJdy5iaW5kKCdjbWRrJywgYnV0dG9ucy5raWxsYnV0dG9uLnB1c2gpCisJCXcuYmluZCgnY21kcycsIGJ1dHRvbnMuc3RlcGJ1dHRvbi5wdXNoKQorCQl3LmJpbmQoJ2NtZHQnLCBidXR0b25zLnN0ZXBpbmJ1dHRvbi5wdXNoKQorCQl3LmJpbmQoJ2NtZHUnLCBidXR0b25zLnN0ZXBvdXRidXR0b24ucHVzaCkKKwkJCisJCXcuYmluZCgnPGNsb3NlPicsIHNlbGYuY2xvc2UpCisJCQorCQl3Lm9wZW4oKQorCQl3Lnh4eF9fX3NlbGVjdCh3LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlKQorCQorCWRlZiBtYWtlb3B0aW9uc21lbnUoc2VsZik6CisJCW9wdGlvbnMgPSBbKCdDbGVhciBicmVha3BvaW50cycsIHNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZS5jbGVhcmJyZWFrcG9pbnRzKSwgCisJCQkJKCdDbGVhciBhbGwgYnJlYWtwb2ludHMnLCBzZWxmLmNsZWFyX2FsbF9icmVha3MpLAorCQkJCSgnRWRpdCBicmVha3BvaW50c4onLCBzZWxmLmVkaXRfYnJlYWtzKSwgJy0nLAorCQkJCShzZWxmLnRyYWNlbWFnaWMgYW5kIAorCQkJCQknRGlzYWJsZSBfX21hZ2ljX18gdHJhY2luZycgb3IgJ0VuYWJsZSBfX21hZ2ljX18gdHJhY2luZycsIHNlbGYudG9nZ2xlbWFnaWMpXQorCQlzZWxmLncucGFuZXMuYm90dG9tLnNyYy5vcHRpb25zbWVudS5zZXQob3B0aW9ucykKKwkKKwlkZWYgZWRpdF9icmVha3Moc2VsZik6CisJCWlmIHNlbGYuYnJlYWtzdmlld2VyOgorCQkJc2VsZi5icmVha3N2aWV3ZXIuc2VsZWN0KCkKKwkJZWxzZToKKwkJCXNlbGYuYnJlYWtzdmlld2VyID0gQnJlYWtwb2ludHNWaWV3ZXIoc2VsZikKKwkKKwlkZWYgdG9nZ2xlbWFnaWMoc2VsZik6CisJCXNlbGYudHJhY2VtYWdpYyA9IG5vdCBzZWxmLnRyYWNlbWFnaWMKKwkKKwlkZWYgc2V0c3RhdGUoc2VsZiwgc3RhdGUpOgorCQlzZWxmLncucGFuZXMuYm90dG9tLnRyYWNpbmdtb25pdG9yLnJlc2V0KCkKKwkJc2VsZi53LnBhbmVzLmJvdHRvbS5zdGF0ZS5zZXQoc2VsZi5yZWFzb24pCisJCWJ1dHRvbnMgPSBzZWxmLncucGFuZXMuYm90dG9tLmJ1dHRvbnMKKwkJaWYgc3RhdGUgPT0gJ3N0b3BwZWQnOgorCQkJYnV0dG9ucy5ydW5idXR0b24uZW5hYmxlKDEpCisJCQlidXR0b25zLnN0b3BidXR0b24uZW5hYmxlKDApCisJCQlidXR0b25zLmtpbGxidXR0b24uZW5hYmxlKDEpCisJCQlidXR0b25zLnN0ZXBidXR0b24uZW5hYmxlKDEpCisJCQlidXR0b25zLnN0ZXBpbmJ1dHRvbi5lbmFibGUoMSkKKwkJCWJ1dHRvbnMuc3RlcG91dGJ1dHRvbi5lbmFibGUoMSkKKwkJZWxpZiBzdGF0ZSA9PSAncnVubmluZyc6CisJCQlidXR0b25zLnJ1bmJ1dHRvbi5lbmFibGUoMCkKKwkJCWJ1dHRvbnMuc3RvcGJ1dHRvbi5lbmFibGUoMSkKKwkJCWJ1dHRvbnMua2lsbGJ1dHRvbi5lbmFibGUoMSkKKwkJCWJ1dHRvbnMuc3RlcGJ1dHRvbi5lbmFibGUoMCkKKwkJCWJ1dHRvbnMuc3RlcGluYnV0dG9uLmVuYWJsZSgwKQorCQkJYnV0dG9ucy5zdGVwb3V0YnV0dG9uLmVuYWJsZSgwKQorCQllbGlmIHN0YXRlID09ICdpZGxlJzoKKwkJCWJ1dHRvbnMucnVuYnV0dG9uLmVuYWJsZSgwKQorCQkJYnV0dG9ucy5zdG9wYnV0dG9uLmVuYWJsZSgwKQorCQkJYnV0dG9ucy5raWxsYnV0dG9uLmVuYWJsZSgwKQorCQkJYnV0dG9ucy5zdGVwYnV0dG9uLmVuYWJsZSgwKQorCQkJYnV0dG9ucy5zdGVwaW5idXR0b24uZW5hYmxlKDApCisJCQlidXR0b25zLnN0ZXBvdXRidXR0b24uZW5hYmxlKDApCisJCWVsaWYgc3RhdGUgPT0gJ2RlYWQnOgorCQkJYnV0dG9ucy5ydW5idXR0b24uZW5hYmxlKDApCisJCQlidXR0b25zLnN0b3BidXR0b24uZW5hYmxlKDApCisJCQlidXR0b25zLmtpbGxidXR0b24uZW5hYmxlKDEpCisJCQlidXR0b25zLnN0ZXBidXR0b24uZW5hYmxlKDApCisJCQlidXR0b25zLnN0ZXBpbmJ1dHRvbi5lbmFibGUoMCkKKwkJCWJ1dHRvbnMuc3RlcG91dGJ1dHRvbi5lbmFibGUoMCkKKwkJZWxzZToKKwkJCXByaW50ICd1bmtub3duIHN0YXRlOicsIHN0YXRlCisJCisJZGVmIHJlc2V0d2lkZ2V0cyhzZWxmKToKKwkJc2VsZi5yZWFzb24gPSAnJworCQlzZWxmLncucGFuZXMuYm90dG9tLnNyY3RpdGxlLnNldCgnJykKKwkJc2VsZi53LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlLnNldCgnJykKKwkJc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5zdGFja2xpc3Quc3RhY2suc2V0KFtdKQorCQlzZWxmLncucGFuZXMuYnJvd3NlcnBhbmVzLmxvY2Fscy5icm93c2VyLnNldCh7fSkKKwkJc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5nbG9iYWxzLmJyb3dzZXIuc2V0KHt9KQorCQlzZWxmLnNldHN0YXRlKCdpZGxlJykKKwkKKwkjIFcgY2FsbGJhY2tzCisJCisJZGVmIGNsb3NlKHNlbGYpOgorCQlzZWxmLnNldF9xdWl0KCkKKwkJc2VsZi5leGl0X21haW5sb29wKCkKKwkJc2VsZi5jbG9zZWQgPSAxCisJCQorCQlzZWxmLnVucmVnaXN0ZXJfZWRpdG9yKHNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZSwgCisJCQkJc2VsZi53LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlLmZpbGUpCisJCXNlbGYuaG9ycGFuZXMgPSBzZWxmLncucGFuZXMuZ2V0cGFuZXNpemVzKCkKKwkJc2VsZi52ZXJwYW5lcyA9IHNlbGYudy5wYW5lcy5icm93c2VycGFuZXMuZ2V0cGFuZXNpemVzKCkKKwkJc2VsZi5ib3VuZHMgPSBzZWxmLncuZ2V0Ym91bmRzKCkKKwkJcHJlZnMgPSBXLmdldGFwcGxpY2F0aW9uKCkuZ2V0cHJlZnMoKQorCQlwcmVmcy5kZWJ1Z2dlci5icmVha3MgPSBzZWxmLmJyZWFrcworCQlwcmVmcy5kZWJ1Z2dlci53aW5kb3dzZXR0aW5ncyA9IHNlbGYuYm91bmRzLCBzZWxmLmhvcnBhbmVzLCBzZWxmLnZlcnBhbmVzCisJCXByZWZzLmRlYnVnZ2VyLnRyYWNlbWFnaWMgPSBzZWxmLnRyYWNlbWFnaWMKKwkJcHJlZnMuc2F2ZSgpCisJCisJIyBzdGFjayBsaXN0IGNhbGxiYWNrCisJCisJZGVmIGRvX3N0YWNrKHNlbGYsIGlzZGJsKToKKwkJc2VsID0gc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5zdGFja2xpc3Quc3RhY2suZ2V0c2VsZWN0aW9uKCkKKwkJaWYgaXNkYmw6CisJCQlpZiBzZWw6CisJCQkJZnJhbWUsIGxpbmVubyA9IHNlbGYuc3RhY2tbc2VsWzBdICsgMV0KKwkJCQlmaWxlbmFtZSA9IGZyYW1lLmZfY29kZS5jb19maWxlbmFtZQorCQkJCWVkaXRvciA9IHNlbGYudy5fcGFyZW50d2luZG93LnBhcmVudC5vcGVuc2NyaXB0KGZpbGVuYW1lLCBsaW5lbm8pCisJCQkJaWYgc2VsZi5icmVha3MuaGFzX2tleShmaWxlbmFtZSk6CisJCQkJCWVkaXRvci5zaG93YnJlYWtwb2ludHMoMSkKKwkJZWxzZToKKwkJCWlmIHNlbCBhbmQgc2VsIDw+IHNlbGYubGFzdHN0YWNrc2VsOgorCQkJCXNlbGYuc2hvd2ZyYW1lKHNlbFswXSArIDEpCisJCQlzZWxmLmxhc3RzdGFja3NlbCA9IHNlbAorCQorCWRlZiBnZXRlZGl0b3Ioc2VsZiwgZmlsZW5hbWUpOgorCQlpZiBmaWxlbmFtZVs6MV0gPT0gJzwnIGFuZCBmaWxlbmFtZVstMTpdID09ICc+JzoKKwkJCWVkaXRvciA9IFcuZ2V0YXBwbGljYXRpb24oKS5nZXRzY3JpcHQoZmlsZW5hbWVbMTotMV0pCisJCWVsc2U6CisJCQllZGl0b3IgPSBXLmdldGFwcGxpY2F0aW9uKCkuZ2V0c2NyaXB0KGZpbGVuYW1lKQorCQlyZXR1cm4gZWRpdG9yCisJCisJIyBidXR0b24gY2FsbGJhY2tzCisJCisJZGVmIGRvX3J1bihzZWxmKToKKwkJc2VsZi5ydW5uaW5nKCkKKwkJc2VsZi5zZXRfY29udGludWUoKQorCQlzZWxmLmV4aXRfbWFpbmxvb3AoKQorCQorCWRlZiBkb19zdG9wKHNlbGYpOgorCQlzZWxmLnNldF9zdGVwKCkKKwkKKwlkZWYgZG9fa2lsbChzZWxmKToKKwkJc2VsZi5zZXRfcXVpdCgpCisJCXNlbGYuZXhpdF9tYWlubG9vcCgpCisJCXNlbGYucmVzZXR3aWRnZXRzKCkKKwkKKwlkZWYgZG9fc3RlcChzZWxmKToKKwkJc2VsZi5ydW5uaW5nKCkKKwkJc2VsZi5zZXRfbmV4dChzZWxmLmN1cmZyYW1lKQorCQlzZWxmLmV4aXRfbWFpbmxvb3AoKQorCQorCWRlZiBkb19zdGVwaW4oc2VsZik6CisJCXNlbGYucnVubmluZygpCisJCXNlbGYuc2V0X3N0ZXAoKQorCQlzZWxmLmV4aXRfbWFpbmxvb3AoKQorCQorCWRlZiBkb19zdGVwb3V0KHNlbGYpOgorCQlzZWxmLnJ1bm5pbmcoKQorCQlzZWxmLnNldF9yZXR1cm4oc2VsZi5jdXJmcmFtZSkKKwkJc2VsZi5leGl0X21haW5sb29wKCkKKwkKKwlkZWYgcnVubmluZyhzZWxmKToKKwkJVy5TZXRDdXJzb3IoJ3dhdGNoJykKKwkJc2VsZi5yZWFzb24gPSAnUnVubmluZ4onCisJCXNlbGYuc2V0c3RhdGUoJ3J1bm5pbmcnKQorCQkjc2VsZi53LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlLnNldCgnJykKKwkJI3NlbGYudy5wYW5lcy5icm93c2VycGFuZXMuc3RhY2tsaXN0LnN0YWNrLnNldChbXSkKKwkJI3NlbGYudy5wYW5lcy5icm93c2VycGFuZXMubG9jYWxzLmJyb3dzZXIuc2V0KHt9KQorCQkjc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5nbG9iYWxzLmJyb3dzZXIuc2V0KHt9KQorCQorCWRlZiBleGl0X21haW5sb29wKHNlbGYpOgorCQlzZWxmLncucGFyZW50LmRlYnVnZ2VyX3F1aXR0aW5nID0gMQorCQorCSMKKwkKKwlkZWYgc2hvd2ZyYW1lKHNlbGYsIHN0YWNraW5kZXgpOgorCQkoZnJhbWUsIGxpbmVubykgPSBzZWxmLnN0YWNrW3N0YWNraW5kZXhdCisJCVcuU2V0Q3Vyc29yKCd3YXRjaCcpCisJCWZpbGVuYW1lID0gZnJhbWUuZl9jb2RlLmNvX2ZpbGVuYW1lCisJCWlmIGZpbGVuYW1lIDw+IHNlbGYuZmlsZToKKwkJCWVkaXRvciA9IHNlbGYuZ2V0ZWRpdG9yKGZpbGVuYW1lKQorCQkJaWYgZWRpdG9yOgorCQkJCXNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZS5zZXQoZWRpdG9yLmdldCgpLCBmaWxlbmFtZSkKKwkJCWVsc2U6CisJCQkJdHJ5OgorCQkJCQlmID0gb3BlbihmaWxlbmFtZSwgJ3JiJykKKwkJCQkJZGF0YSA9IGYucmVhZCgpCisJCQkJCWYuY2xvc2UoKQorCQkJCWV4Y2VwdCBJT0Vycm9yOgorCQkJCQlpZiBmaWxlbmFtZVstMzpdID09ICcucHknOgorCQkJCQkJaW1wb3J0IGltcAorCQkJCQkJbW9kbmFtZSA9IG9zLnBhdGguYmFzZW5hbWUoZmlsZW5hbWUpWzotM10KKwkJCQkJCXRyeToKKwkJCQkJCQlmLCBmaWxlbmFtZSwgKHN1ZmYsIG1vZGUsIGR1bW15KSA9IGltcC5maW5kX21vZHVsZShtb2RuYW1lKQorCQkJCQkJZXhjZXB0IEltcG9ydEVycm9yOgorCQkJCQkJCXNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZS5zZXQoJ2Nhbrl0IGZpbmQgZmlsZScpCisJCQkJCQllbHNlOgorCQkJCQkJCWYuY2xvc2UoKQorCQkJCQkJCWlmIHN1ZmYgPT0gJy5weSc6CisJCQkJCQkJCWYgPSBvcGVuKGZpbGVuYW1lLCAncmInKQorCQkJCQkJCQlkYXRhID0gZi5yZWFkKCkKKwkJCQkJCQkJZi5jbG9zZSgpCisJCQkJCQkJCXNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZS5zZXQoZGF0YSwgZmlsZW5hbWUpCisJCQkJCQkJZWxzZToKKwkJCQkJCQkJc2VsZi53LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlLnNldCgnY2FuuXQgZmluZCBmaWxlJykKKwkJCQkJZWxzZToKKwkJCQkJCXNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZS5zZXQoJ2Nhbrl0IGZpbmQgZmlsZScpCisJCQkJZWxzZToKKwkJCQkJc2VsZi53LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlLnNldChkYXRhLCBmaWxlbmFtZSkKKwkJCXNlbGYuZmlsZSA9IGZpbGVuYW1lCisJCXNlbGYudy5wYW5lcy5ib3R0b20uc3JjdGl0bGUuc2V0KCdTb3VyY2U6ICcgKyBmaWxlbmFtZSArICgobGluZW5vID4gMCkgYW5kICgnIChsaW5lICVkKScgJSBsaW5lbm8pIG9yICcgJykpCisJCXNlbGYuZ290b19saW5lKGxpbmVubykKKwkJc2VsZi5saW5lbm8gPSBsaW5lbm8KKwkJc2VsZi5zaG93dmFycygoZnJhbWUsIGxpbmVubykpCisJCisJZGVmIHNob3d2YXJzKHNlbGYsIChmcmFtZSwgbGluZW5vKSk6CisJCWlmIGZyYW1lLmZfbG9jYWxzIGlzIG5vdCBmcmFtZS5mX2dsb2JhbHM6CisJCQlsb2NhbHMgPSBmcmFtZS5mX2xvY2FscworCQllbHNlOgorCQkJbG9jYWxzID0geydTYW1lIGFzIEdsb2JhbHMnOicnfQorCQlmaWx0ZXJlZGxvY2FscyA9IHt9CisJCWZvciBrZXksIHZhbHVlIGluIGxvY2Fscy5pdGVtcygpOgorCQkJIyBlbXB0eSBrZXkgaXMgbWFnaWMgZm9yIFB5dGhvbiAxLjQ7ICcuJyBpcyBtYWdpYyBmb3IgMS41Li4uCisJCQlpZiBub3Qga2V5IG9yIGtleVswXSA8PiAnLic6CisJCQkJZmlsdGVyZWRsb2NhbHNba2V5XSA9IHZhbHVlCisJCXNlbGYudy5wYW5lcy5icm93c2VycGFuZXMubG9jYWxzLmJyb3dzZXIuc2V0KGZpbHRlcmVkbG9jYWxzKQorCQlzZWxmLncucGFuZXMuYnJvd3NlcnBhbmVzLmdsb2JhbHMuYnJvd3Nlci5zZXQoZnJhbWUuZl9nbG9iYWxzKQorCQorCWRlZiBzaG93c3RhY2soc2VsZiwgc3RhY2tpbmRleCk6CisJCXN0YWNrID0gW10KKwkJZm9yIGZyYW1lLCBsaW5lbm8gaW4gc2VsZi5zdGFja1sxOl06CisJCQlmaWxlbmFtZSA9IGZyYW1lLmZfY29kZS5jb19maWxlbmFtZQorCQkJdHJ5OgorCQkJCWZpbGVuYW1lID0gX2ZpbGVuYW1lc1tmaWxlbmFtZV0KKwkJCWV4Y2VwdCBLZXlFcnJvcjoKKwkJCQlpZiBmaWxlbmFtZVs6MV0gKyBmaWxlbmFtZVstMTpdIDw+ICc8Pic6CisJCQkJCWZpbGVuYW1lID0gb3MucGF0aC5iYXNlbmFtZShmaWxlbmFtZSkKKwkJCQlfZmlsZW5hbWVzW2ZyYW1lLmZfY29kZS5jb19maWxlbmFtZV0gPSBmaWxlbmFtZQorCQkJZnVuY25hbWUgPSBmcmFtZS5mX2NvZGUuY29fbmFtZQorCQkJaWYgZnVuY25hbWUgPT0gJz8nOgorCQkJCWZ1bmNuYW1lID0gJzx0b3BsZXZlbD4nCisJCQlzdGFjay5hcHBlbmQoZmlsZW5hbWUgKyAnOiAnICsgZnVuY25hbWUpCisJCWlmIHN0YWNrIDw+IHNlbGYubGFzdHN0YWNrOgorCQkJc2VsZi53LnBhbmVzLmJyb3dzZXJwYW5lcy5zdGFja2xpc3Quc3RhY2suc2V0KHN0YWNrKQorCQkJc2VsZi5sYXN0c3RhY2sgPSBzdGFjaworCQlzZWwgPSBbc3RhY2tpbmRleCAtIDFdCisJCXNlbGYudy5wYW5lcy5icm93c2VycGFuZXMuc3RhY2tsaXN0LnN0YWNrLnNldHNlbGVjdGlvbihzZWwpCisJCXNlbGYubGFzdHN0YWNrc2VsID0gc2VsCisJCisJZGVmIGdvdG9fbGluZShzZWxmLCBsaW5lbm8pOgorCQlpZiBsaW5lbm8gPiAwOgorCQkJc2VsZi53LnBhbmVzLmJvdHRvbS5zcmMuc291cmNlLnNlbGVjdGxpbmUobGluZW5vIC0gMSkKKwkJZWxzZToKKwkJCXNlbGYudy5wYW5lcy5ib3R0b20uc3JjLnNvdXJjZS5zZXRzZWxlY3Rpb24oMCwgMCkKKwkKKwkjIGJkYiBlbnRyeSBwb2ludHMKKwkKKyMJZGVmIHVzZXJfY2FsbChzZWxmLCBmcmFtZSwgYXJndW1lbnRfbGlzdCk6CisjCQlzZWxmLnJlYXNvbiA9ICdDYWxsaW5nJworIwkJc2VsZi5pbnRlcmFjdGlvbihmcmFtZSwgTm9uZSkKKwkKKwlkZWYgdXNlcl9saW5lKHNlbGYsIGZyYW1lKToKKwkJIyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCB3aGVuIHdlIHN0b3Agb3IgYnJlYWsgYXQgdGhpcyBsaW5lCisJCXNlbGYucmVhc29uID0gJ1N0b3BwZWQnCisJCXNlbGYuaW50ZXJhY3Rpb24oZnJhbWUsIE5vbmUpCisJCisJZGVmIHVzZXJfcmV0dXJuKHNlbGYsIGZyYW1lLCByZXR1cm5fdmFsdWUpOgorCQkjIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gYSByZXR1cm4gdHJhcCBpcyBzZXQgaGVyZQorCQlmbmFtZSA9IGZyYW1lLmZfY29kZS5jb19uYW1lCisJCWlmIGZuYW1lIDw+ICc/JzoKKwkJCXNlbGYucmVhc29uID0gJ1JldHVybmluZyBmcm9tICVzKCknICUgZnJhbWUuZl9jb2RlLmNvX25hbWUKKwkJCWZyYW1lLmZfbG9jYWxzWydfX3JldHVybl9fJ10gPSByZXR1cm5fdmFsdWUKKwkJZWxpZiBmcmFtZS5mX2JhY2sgaXMgc2VsZi5ib3RmcmFtZToKKwkJCXNlbGYucmVhc29uID0gJ0RvbmUnCisJCWVsc2U6CisJCQlzZWxmLnJlYXNvbiA9ICdSZXR1cm5pbmcnCisJCXNlbGYuaW50ZXJhY3Rpb24oZnJhbWUsIE5vbmUsIDEpCisJCisJZGVmIHVzZXJfZXhjZXB0aW9uKHNlbGYsIGZyYW1lLCAoZXhjX3R5cGUsIGV4Y192YWx1ZSwgZXhjX3RyYWNlYmFjaykpOgorCQkjIFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIHdoZW4gd2Ugc3RvcCBvciBicmVhayBhdCB0aGlzIGxpbmUKKwkJc2VsZi5yZWFzb24gPSBzZWxmLmZvcm1hdGV4Y2VwdGlvbihleGNfdHlwZSwgZXhjX3ZhbHVlKQorCQlzZWxmLmludGVyYWN0aW9uKGZyYW1lLCBleGNfdHJhY2ViYWNrKQorCQorCWRlZiBmb3JtYXRleGNlcHRpb24oc2VsZiwgZXhjX3R5cGUsIGV4Y192YWx1ZSk6CisJCWlmIGV4Y190eXBlID09IFN5bnRheEVycm9yOgorCQkJdHJ5OgorCQkJCXZhbHVlLCAoZmlsZW5hbWUsIGxpbmVubywgY2hhcm5vLCBsaW5lKSA9IGV4Y192YWx1ZQorCQkJZXhjZXB0OgorCQkJCXBhc3MKKwkJCWVsc2U6CisJCQkJcmV0dXJuIHN0cihleGNfdHlwZSkgKyAnOiAnICsgc3RyKHZhbHVlKQorCQlpZiB0eXBlKGV4Y190eXBlKSA9PSB0eXBlcy5DbGFzc1R5cGU6CisJCQluaWNlID0gZXhjX3R5cGUuX19uYW1lX18KKwkJZWxzZToKKwkJCW5pY2UgPSBzdHIoZXhjX3R5cGUpCisJCXZhbHVlID0gc3RyKGV4Y192YWx1ZSkKKwkJaWYgZXhjX3ZhbHVlIGFuZCB2YWx1ZToKKwkJCW5pY2UgPSBuaWNlICsgIjogIiArIHZhbHVlCisJCXJldHVybiBuaWNlCisJCisJZGVmIGZvcmdldChzZWxmKToKKwkJc2VsZi5zdGFjayA9IFtdCisJCXNlbGYuY3VyaW5kZXggPSAwCisJCXNlbGYuY3VyZnJhbWUgPSBOb25lCisJCisJZGVmIHNldHVwKHNlbGYsIGYsIHQsIGlzcmV0dXJuaW5nID0gMCk6CisJCXNlbGYuZm9yZ2V0KCkKKwkJc2VsZi5zdGFjaywgc2VsZi5jdXJpbmRleCA9IHNlbGYuZ2V0X3N0YWNrKGYsIHQpCisJCXNlbGYuY3VyZnJhbWUgPSBzZWxmLnN0YWNrW3NlbGYuY3VyaW5kZXggLSBpc3JldHVybmluZ11bMF0KKwkKKwlkZWYgaW50ZXJhY3Rpb24oc2VsZiwgZnJhbWUsIHRyYWNlYmFjaywgaXNyZXR1cm5pbmcgPSAwKToKKwkJc2F2ZXBvcnQgPSBRZC5HZXRQb3J0KCkKKwkJc2VsZi53LnNlbGVjdCgpCisJCXRyeToKKwkJCXNlbGYuc2V0dXAoZnJhbWUsIHRyYWNlYmFjaywgaXNyZXR1cm5pbmcpCisJCQlzZWxmLnNldHN0YXRlKCdzdG9wcGVkJykKKwkJCXN0YWNraW5kZXggPSBzZWxmLmN1cmluZGV4CisJCQlpZiBpc3JldHVybmluZzoKKwkJCQlpZiBmcmFtZS5mX2JhY2sgaXMgbm90IHNlbGYuYm90ZnJhbWU6CisJCQkJCXN0YWNraW5kZXggPSBzdGFja2luZGV4IC0gMQorCQkJc2VsZi5zaG93c3RhY2soc3RhY2tpbmRleCkKKwkJCXNlbGYuc2hvd2ZyYW1lKHN0YWNraW5kZXgpCisJCQlzZWxmLncucGFyZW50LmRlYnVnZ2VyX21haW5sb29wKCkKKwkJCXNlbGYuZm9yZ2V0KCkKKwkJZmluYWxseToKKwkJCVFkLlNldFBvcnQoc2F2ZXBvcnQpCisJCisJIyBiZGIgY3VzdG9taXphdGlvbgorCQorCWRlZiB0cmFjZV9kaXNwYXRjaChzZWxmLCBmcmFtZSwgZXZlbnQsIGFyZywgVGlja0NvdW50ID0gRXZ0LlRpY2tDb3VudCk6CisJCWlmIFRpY2tDb3VudCgpIC0gc2VsZi50cmFjaW5nbW9uaXRvcnRpbWUgPiAxNToKKwkJCXNlbGYudHJhY2luZ21vbml0b3J0aW1lID0gVGlja0NvdW50KCkKKwkJCXNlbGYudy5wYW5lcy5ib3R0b20udHJhY2luZ21vbml0b3IudG9nZ2xlKCkKKwkJdHJ5OgorCQkJdHJ5OgorCQkJCU1hY09TLkVuYWJsZUFwcHN3aXRjaCgwKQorCQkJCWlmIHNlbGYucXVpdHRpbmc6CisJCQkJCSMgcmV0dXJuaW5nIE5vbmUgaXMgbm90IGVub3VnaCwgYSBmb3JtZXIgQmRiUXVpdCBleGNlcHRpb24KKwkJCQkJIyBtaWdodCBoYXZlIGJlZW4gZWF0ZW4gYnkgdGhlIHByaW50IHN0YXRlbWVudAorCQkJCQlyYWlzZSBiZGIuQmRiUXVpdAorCQkJCWlmIGV2ZW50ID09ICdsaW5lJzoKKwkJCQkJcmV0dXJuIHNlbGYuZGlzcGF0Y2hfbGluZShmcmFtZSkKKwkJCQlpZiBldmVudCA9PSAnY2FsbCc6CisJCQkJCXJldHVybiBzZWxmLmRpc3BhdGNoX2NhbGwoZnJhbWUsIGFyZykKKwkJCQlpZiBldmVudCA9PSAncmV0dXJuJzoKKwkJCQkJcmV0dXJuIHNlbGYuZGlzcGF0Y2hfcmV0dXJuKGZyYW1lLCBhcmcpCisJCQkJaWYgZXZlbnQgPT0gJ2V4Y2VwdGlvbic6CisJCQkJCXJldHVybiBzZWxmLmRpc3BhdGNoX2V4Y2VwdGlvbihmcmFtZSwgYXJnKQorCQkJCXByaW50ICdiZGIuQmRiLmRpc3BhdGNoOiB1bmtub3duIGRlYnVnZ2luZyBldmVudDonLCBgZXZlbnRgCisJCQkJcmV0dXJuIHNlbGYudHJhY2VfZGlzcGF0Y2gKKwkJCWZpbmFsbHk6CisJCQkJTWFjT1MuRW5hYmxlQXBwc3dpdGNoKC0xKQorCQlleGNlcHQgS2V5Ym9hcmRJbnRlcnJ1cHQ6CisJCQlzZWxmLnNldF9zdGVwKCkKKwkJCXJldHVybiBzZWxmLnRyYWNlX2Rpc3BhdGNoCisJCWV4Y2VwdCBiZGIuQmRiUXVpdDoKKwkJCWlmIHNlbGYuY29udGludWV3aXRob3V0ZGVidWdnZXI6CisJCQkJc2VsZi5jbGVhcl90cmFjZWZ1bmNzKCkKKwkJCQlyZXR1cm4KKwkJCWVsc2U6CisJCQkJcmFpc2UgYmRiLkJkYlF1aXQKKwkJZXhjZXB0OgorCQkJcHJpbnQgJ1hYWCBFeGNlcHRpb24gZHVyaW5nIGRlYnVnZ2VyIGludGVyYWN0aW9uLicsIFwKKwkJCQkJc2VsZi5mb3JtYXRleGNlcHRpb24oc3lzLmV4Y190eXBlLCBzeXMuZXhjX3ZhbHVlKQorCQkJcmV0dXJuIHNlbGYudHJhY2VfZGlzcGF0Y2gKKwkKKwlkZWYgZGlzcGF0Y2hfY2FsbChzZWxmLCBmcmFtZSwgYXJnKToKKwkJaWYgbm90IHNlbGYudHJhY2VtYWdpYyBhbmQgXAorCQkJCWZyYW1lLmZfY29kZS5jb19uYW1lWzoyXSA9PSAnX18nID09IGZyYW1lLmZfY29kZS5jb19uYW1lWy0yOl0gYW5kIFwKKwkJCQlmcmFtZS5mX2NvZGUuY29fbmFtZSA8PiAnX19pbml0X18nOgorCQkJcmV0dXJuCisJCWlmIHNlbGYuYm90ZnJhbWUgaXMgTm9uZToKKwkJCSMgRmlyc3QgY2FsbCBvZiBkaXNwYXRjaCBzaW5jZSByZXNldCgpCisJCQlzZWxmLmJvdGZyYW1lID0gZnJhbWUuZl9iYWNrCSMgeHh4ICEhISBhZGRlZCBmX2JhY2sKKwkJCXJldHVybiBzZWxmLnRyYWNlX2Rpc3BhdGNoCisJCWlmIG5vdCAoc2VsZi5zdG9wX2hlcmUoZnJhbWUpIG9yIHNlbGYuYnJlYWtfYW55d2hlcmUoZnJhbWUpKToKKwkJCSMgTm8gbmVlZCB0byB0cmFjZSB0aGlzIGZ1bmN0aW9uCisJCQlyZXR1cm4gIyBOb25lCisJCXNlbGYudXNlcl9jYWxsKGZyYW1lLCBhcmcpCisJCWlmIHNlbGYucXVpdHRpbmc6CisJCQlyYWlzZSBiZGIuQmRiUXVpdAorCQlyZXR1cm4gc2VsZi50cmFjZV9kaXNwYXRjaAorCQorCWRlZiBzZXRfY29udGludWUoc2VsZik6CisJCSMgRG9uJ3Qgc3RvcCBleGNlcHQgYXQgYnJlYWtwb2ludHMgb3Igd2hlbiBmaW5pc2hlZAorCQlzZWxmLnN0b3BmcmFtZSA9IHNlbGYuYm90ZnJhbWUKKwkJc2VsZi5yZXR1cm5mcmFtZSA9IE5vbmUKKwkJc2VsZi5xdWl0dGluZyA9IDAKKwkJIyB1bmxpa2UgaW4gYmRiL3BkYiwgdGhlcmUncyBhIGNoYW5jZSB0aGF0IGJyZWFrcG9pbnRzIGNoYW5nZSAKKwkJIyAqd2hpbGUqIGEgcHJvZ3JhbSAodGhpcyBwcm9ncmFtIDstKSBpcyBydW5uaW5nLiBJdCdzIGFjdHVhbGx5IHF1aXRlIGxpa2VseS4KKwkJIyBTbyB3ZSBkb24ndCBkZWxldGUgZnJhbWUuZl90cmFjZSB1bnRpbCB0aGUgYm90dG9tIGZyYW1lIGlmIHRoZXJlIGFyZSBubyBicmVha3BvaW50cy4KKwkKKwlkZWYgc2V0X2JyZWFrKHNlbGYsIGZpbGVuYW1lLCBsaW5lbm8pOgorCQlpZiBub3Qgc2VsZi5icmVha3MuaGFzX2tleShmaWxlbmFtZSk6CisJCQlzZWxmLmJyZWFrc1tmaWxlbmFtZV0gPSBbXQorCQlsaXN0ID0gc2VsZi5icmVha3NbZmlsZW5hbWVdCisJCWlmIGxpbmVubyBpbiBsaXN0OgorCQkJcmV0dXJuICdUaGVyZSBpcyBhbHJlYWR5IGEgYnJlYWtwb2ludCB0aGVyZSEnCisJCWxpc3QuYXBwZW5kKGxpbmVubykKKwkJbGlzdC5zb3J0KCkJIyBJIHdhbnQgdG8ga2VlcCB0aGVtIG5lYXRseSBzb3J0ZWQ7IGVhc2llciBmb3IgZHJhd2luZworCQlzZWxmLnVwZGF0ZV9icmVha3MoZmlsZW5hbWUpCisJCisJZGVmIGNsZWFyX2JyZWFrKHNlbGYsIGZpbGVuYW1lLCBsaW5lbm8pOgorCQliZGIuQmRiLmNsZWFyX2JyZWFrKHNlbGYsIGZpbGVuYW1lLCBsaW5lbm8pCisJCXNlbGYudXBkYXRlX2JyZWFrcyhmaWxlbmFtZSkKKwkKKwlkZWYgY2xlYXJfYWxsX2ZpbGVfYnJlYWtzKHNlbGYsIGZpbGVuYW1lKToKKwkJYmRiLkJkYi5jbGVhcl9hbGxfZmlsZV9icmVha3Moc2VsZiwgZmlsZW5hbWUpCisJCXNlbGYudXBkYXRlX2JyZWFrcyhmaWxlbmFtZSkKKwkKKwlkZWYgY2xlYXJfYWxsX2JyZWFrcyhzZWxmKToKKwkJYmRiLkJkYi5jbGVhcl9hbGxfYnJlYWtzKHNlbGYpCisJCWZvciBlZGl0b3JzIGluIHNlbGYuZWRpdG9ycy52YWx1ZXMoKToKKwkJCWZvciBlZGl0b3IgaW4gZWRpdG9yczoKKwkJCQllZGl0b3IuZHJhd2JyZWFrcG9pbnRzKCkKKwkKKwkjIHNwZWNpYWwKKwkKKwlkZWYgdG9nZ2xlX2JyZWFrKHNlbGYsIGZpbGVuYW1lLCBsaW5lbm8pOgorCQlpZiBzZWxmLmdldF9icmVhayhmaWxlbmFtZSwgbGluZW5vKToKKwkJCXNlbGYuY2xlYXJfYnJlYWsoZmlsZW5hbWUsIGxpbmVubykKKwkJZWxzZToKKwkJCXNlbGYuc2V0X2JyZWFrKGZpbGVuYW1lLCBsaW5lbm8pCisJCisJZGVmIGNsZWFyX2JyZWFrc19hYm92ZShzZWxmLCBmaWxlbmFtZSwgYWJvdmUpOgorCQlpZiBub3Qgc2VsZi5icmVha3MuaGFzX2tleShmaWxlbmFtZSk6CisJCQlyZXR1cm4gJ1RoZXJlIGFyZSBubyBicmVha3BvaW50cyBpbiB0aGF0IGZpbGUhJworCQlmb3IgbGluZW5vIGluIHNlbGYuYnJlYWtzW2ZpbGVuYW1lXVs6XToKKwkJCWlmIGxpbmVubyA+IGFib3ZlOgorCQkJCXNlbGYuYnJlYWtzW2ZpbGVuYW1lXS5yZW1vdmUobGluZW5vKQorCQlpZiBub3Qgc2VsZi5icmVha3NbZmlsZW5hbWVdOgorCQkJZGVsIHNlbGYuYnJlYWtzW2ZpbGVuYW1lXQorCQorCSMgZWRpdG9yIHN0dWZmCisJCisJZGVmIHVwZGF0ZV9icmVha3Moc2VsZiwgZmlsZW5hbWUpOgorCQlpZiBzZWxmLmJyZWFrc3ZpZXdlcjoKKwkJCXNlbGYuYnJlYWtzdmlld2VyLnVwZGF0ZSgpCisJCWlmIHNlbGYuZWRpdG9ycy5oYXNfa2V5KGZpbGVuYW1lKToKKwkJCWZvciBlZGl0b3IgaW4gc2VsZi5lZGl0b3JzW2ZpbGVuYW1lXToKKwkJCQlpZiBlZGl0b3IuX2RlYnVnZ2VyOgkjIFhYWAorCQkJCQllZGl0b3IuZHJhd2JyZWFrcG9pbnRzKCkKKwkJCQllbHNlOgorCQkJCQlwcmludCAneHh4IGRlYWQgZWRpdG9yIScKKwkKKwlkZWYgdXBkYXRlX2FsbGJyZWFrcyhzZWxmKToKKwkJaWYgc2VsZi5icmVha3N2aWV3ZXI6CisJCQlzZWxmLmJyZWFrc3ZpZXdlci51cGRhdGUoKQorCQlmb3IgZmlsZW5hbWUgaW4gc2VsZi5icmVha3Mua2V5cygpOgorCQkJaWYgc2VsZi5lZGl0b3JzLmhhc19rZXkoZmlsZW5hbWUpOgorCQkJCWZvciBlZGl0b3IgaW4gc2VsZi5lZGl0b3JzW2ZpbGVuYW1lXToKKwkJCQkJaWYgZWRpdG9yLl9kZWJ1Z2dlcjoJIyBYWFgKKwkJCQkJCWVkaXRvci5kcmF3YnJlYWtwb2ludHMoKQorCQkJCQllbHNlOgorCQkJCQkJcHJpbnQgJ3h4eCBkZWFkIGVkaXRvciEnCisJCisJZGVmIHJlZ2lzdGVyX2VkaXRvcihzZWxmLCBlZGl0b3IsIGZpbGVuYW1lKToKKwkJaWYgbm90IGZpbGVuYW1lOgorCQkJcmV0dXJuCisJCWlmIG5vdCBzZWxmLmVkaXRvcnMuaGFzX2tleShmaWxlbmFtZSk6CisJCQlzZWxmLmVkaXRvcnNbZmlsZW5hbWVdID0gW2VkaXRvcl0KKwkJZWxpZiBlZGl0b3Igbm90IGluIHNlbGYuZWRpdG9yc1tmaWxlbmFtZV06CisJCQlzZWxmLmVkaXRvcnNbZmlsZW5hbWVdLmFwcGVuZChlZGl0b3IpCisJCisJZGVmIHVucmVnaXN0ZXJfZWRpdG9yKHNlbGYsIGVkaXRvciwgZmlsZW5hbWUpOgorCQlpZiBub3QgZmlsZW5hbWU6CisJCQlyZXR1cm4KKwkJdHJ5OgorCQkJc2VsZi5lZGl0b3JzW2ZpbGVuYW1lXS5yZW1vdmUoZWRpdG9yKQorCQkJaWYgbm90IHNlbGYuZWRpdG9yc1tmaWxlbmFtZV06CisJCQkJZGVsIHNlbGYuZWRpdG9yc1tmaWxlbmFtZV0KKwkJCQkjIGlmIHRoaXMgd2FzIGFuIHVudGl0bGVkIHdpbmRvdywgY2xlYXIgdGhlIGJyZWFrcy4KKwkJCQlpZiBmaWxlbmFtZVs6MV0gPT0gJzwnIGFuZCBmaWxlbmFtZVstMTpdID09ICc+JyBhbmQgXAorCQkJCQkJc2VsZi5icmVha3MuaGFzX2tleShmaWxlbmFtZSk6CisJCQkJCXNlbGYuY2xlYXJfYWxsX2ZpbGVfYnJlYWtzKGZpbGVuYW1lKQorCQlleGNlcHQgKEtleUVycm9yLCBWYWx1ZUVycm9yKToKKwkJCXBhc3MKKwkJCisKK2NsYXNzIFNvdXJjZVZpZXdlcihXLlB5RWRpdG9yKToKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgKmFyZ3MsICoqa3dhcmdzKToKKwkJYXBwbHkoVy5QeUVkaXRvci5fX2luaXRfXywgKHNlbGYsKSArIGFyZ3MsIGt3YXJncykKKwkJc2VsZi5iaW5kKCc8Y2xpY2s+Jywgc2VsZi5jbGlja2ludGVyY2VwdCkKKwkKKwlkZWYgY2xpY2tpbnRlcmNlcHQoc2VsZiwgcG9pbnQsIG1vZGlmaWVycyk6CisJCWlmIHNlbGYuX3BhcmVudHdpbmRvdy5fY3VycmVudHdpZGdldCA8PiBzZWxmIGFuZCBub3Qgc2VsZi5wdF9pbl9icmVha3MocG9pbnQpOgorCQkJc2VsZi5fcGFyZW50d2luZG93Lnh4eF9fX3NlbGVjdChzZWxmKQorCQkJcmV0dXJuIDEKKwkKKwlkZWYgX2dldHZpZXdyZWN0KHNlbGYpOgorCQlsLCB0LCByLCBiID0gc2VsZi5fYm91bmRzCisJCWlmIHNlbGYuX2RlYnVnZ2VyOgorCQkJcmV0dXJuIChsICsgMTIsIHQgKyAyLCByIC0gMSwgYiAtIDIpCisJCWVsc2U6CisJCQlyZXR1cm4gKGwgKyA1LCB0ICsgMiwgciAtIDEsIGIgLSAyKQorCQorCWRlZiBzZWxlY3Qoc2VsZiwgb25vZmYsIGlzY2xpY2sgPSAwKToKKwkJaWYgVy5TZWxlY3RhYmxlV2lkZ2V0LnNlbGVjdChzZWxmLCBvbm9mZik6CisJCQlyZXR1cm4KKwkJc2VsZi5TZXRQb3J0KCkKKwkJI2lmIG9ub2ZmOgorCQkjCXNlbGYudGVkLldFQWN0aXZhdGUoKQorCQkjZWxzZToKKwkJIwlzZWxmLnRlZC5XRURlYWN0aXZhdGUoKQorCQlzZWxmLmRyYXdzZWxmcmFtZShvbm9mZikKKwkKKwlkZWYgZHJhd3NlbGZyYW1lKHNlbGYsIG9ub2ZmKToKKwkJcGFzcworCisKK2NsYXNzIEJyZWFrcG9pbnRzVmlld2VyOgorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBkZWJ1Z2dlcik6CisJCXNlbGYuZGVidWdnZXIgPSBkZWJ1Z2dlcgorCQlpbXBvcnQgTGlzdHMKKwkJc2VsZi53ID0gVy5XaW5kb3coKDMwMCwgMjUwKSwgJ0JyZWFrcG9pbnRzJywgbWluc2l6ZSA9ICgyMDAsIDIwMCkpCisJCXNlbGYudy5wYW5lcyA9IFcuSG9yaXpvbnRhbFBhbmVzKCg4LCA4LCAtOCwgLTMyKSwgKDAuMywgMC43KSkKKwkJc2VsZi53LnBhbmVzLmZpbGVzID0gVy5MaXN0KE5vbmUsIGNhbGxiYWNrID0gc2VsZi5maWxlaGl0KQkJIywgZmxhZ3MgPSBMaXN0cy5sT25seU9uZSkKKwkJc2VsZi53LnBhbmVzLmdyID0gVy5Hcm91cChOb25lKQorCQlzZWxmLncucGFuZXMuZ3IuYnJlYWtzID0gVy5MaXN0KCgwLCAwLCAtMTMwLCAwKSwgY2FsbGJhY2sgPSBzZWxmLmxpbmVoaXQpCSMsIGZsYWdzID0gTGlzdHMubE9ubHlPbmUpCisJCXNlbGYudy5wYW5lcy5nci5vcGVuYnV0dG9uID0gVy5CdXR0b24oKC04MCwgNCwgMCwgMTYpLCAnVmlld4onLCBzZWxmLm9wZW5idXR0b25oaXQpCisJCXNlbGYudy5wYW5lcy5nci5kZWxldGVidXR0b24gPSBXLkJ1dHRvbigoLTgwLCAyOCwgMCwgMTYpLCAnRGVsZXRlJywgc2VsZi5kZWxldGVidXR0b25oaXQpCisJCQorCQlzZWxmLncuYmluZCgnPGNsb3NlPicsIHNlbGYuY2xvc2UpCisJCXNlbGYudy5iaW5kKCdiYWNrc3BhY2UnLCBzZWxmLncucGFuZXMuZ3IuZGVsZXRlYnV0dG9uLnB1c2gpCisJCQorCQlzZWxmLnNldHVwKCkKKwkJc2VsZi53Lm9wZW4oKQorCQlzZWxmLncucGFuZXMuZ3Iub3BlbmJ1dHRvbi5lbmFibGUoMCkKKwkJc2VsZi53LnBhbmVzLmdyLmRlbGV0ZWJ1dHRvbi5lbmFibGUoMCkKKwkJc2VsZi5jdXJmaWxlID0gTm9uZQorCQorCWRlZiBkZWxldGVidXR0b25oaXQoc2VsZik6CisJCWlmIHNlbGYudy5fY3VycmVudHdpZGdldCA9PSBzZWxmLncucGFuZXMuZmlsZXM6CisJCQlzZWxmLmRlbF9maWxlbmFtZSgpCisJCWVsc2U6CisJCQlzZWxmLmRlbF9udW1iZXIoKQorCQlzZWxmLmNoZWNrYnV0dG9ucygpCisJCisJZGVmIGRlbF9udW1iZXIoc2VsZik6CisJCWlmIHNlbGYuY3VyZmlsZSBpcyBOb25lOgorCQkJcmV0dXJuCisJCXNlbCA9IHNlbGYudy5wYW5lcy5nci5icmVha3MuZ2V0c2VsZWN0ZWRvYmplY3RzKCkKKwkJZm9yIGxpbmVubyBpbiBzZWw6CisJCQlzZWxmLmRlYnVnZ2VyLmNsZWFyX2JyZWFrKHNlbGYuY3VyZmlsZSwgbGluZW5vKQorCQorCWRlZiBkZWxfZmlsZW5hbWUoc2VsZik6CisJCXNlbCA9IHNlbGYudy5wYW5lcy5maWxlcy5nZXRzZWxlY3RlZG9iamVjdHMoKQorCQlmb3IgZmlsZW5hbWUgaW4gc2VsOgorCQkJc2VsZi5kZWJ1Z2dlci5jbGVhcl9hbGxfZmlsZV9icmVha3MoZmlsZW5hbWUpCisJCXNlbGYuZGVidWdnZXIudXBkYXRlX2FsbGJyZWFrcygpCisJCisJZGVmIHNldHVwKHNlbGYpOgorCQlmaWxlcyA9IHNlbGYuZGVidWdnZXIuYnJlYWtzLmtleXMoKQorCQlmaWxlcy5zb3J0KCkKKwkJc2VsZi53LnBhbmVzLmZpbGVzLnNldChmaWxlcykKKwkKKwlkZWYgY2xvc2Uoc2VsZik6CisJCXNlbGYuZGVidWdnZXIuYnJlYWtzdmlld2VyID0gTm9uZQorCQlzZWxmLmRlYnVnZ2VyID0gTm9uZQorCQorCWRlZiB1cGRhdGUoc2VsZik6CisJCXNlbCA9IHNlbGYudy5wYW5lcy5maWxlcy5nZXRzZWxlY3RlZG9iamVjdHMoKQorCQlzZWxmLnNldHVwKCkKKwkJc2VsZi53LnBhbmVzLmZpbGVzLnNldHNlbGVjdGVkb2JqZWN0cyhzZWwpCisJCXNlbCA9IHNlbGYudy5wYW5lcy5maWxlcy5nZXRzZWxlY3Rpb24oKQorCQlpZiBsZW4oc2VsKSA9PSAwIGFuZCBzZWxmLmN1cmZpbGU6CisJCQlzZWxmLncucGFuZXMuZmlsZXMuc2V0c2VsZWN0ZWRvYmplY3RzKFtzZWxmLmN1cmZpbGVdKQorCQlzZWxmLmZpbGVoaXQoMCkKKwkKKwlkZWYgc2VsZWN0KHNlbGYpOgorCQlzZWxmLncuc2VsZWN0KCkKKwkKKwlkZWYgc2VsZWN0ZmlsZShzZWxmLCBmaWxlKToKKwkJc2VsZi53LnBhbmVzLmZpbGVzLnNldHNlbGVjdGVkb2JqZWN0cyhbZmlsZV0pCisJCXNlbGYuZmlsZWhpdCgwKQkJCQorCQorCWRlZiBvcGVuYnV0dG9uaGl0KHNlbGYpOgorCQlzZWxmLmZpbGVoaXQoMSkKKwkKKwlkZWYgZmlsZWhpdChzZWxmLCBpc2RibCk6CisJCXNlbCA9IHNlbGYudy5wYW5lcy5maWxlcy5nZXRzZWxlY3RlZG9iamVjdHMoKQorCQlpZiBpc2RibDoKKwkJCWZvciBmaWxlbmFtZSBpbiBzZWw6CisJCQkJbGluZW5vID0gTm9uZQorCQkJCWlmIGZpbGVuYW1lID09IHNlbGYuY3VyZmlsZToKKwkJCQkJbGluZXNlbCA9IHNlbGYudy5wYW5lcy5nci5icmVha3MuZ2V0c2VsZWN0ZWRvYmplY3RzKCkKKwkJCQkJaWYgbGluZXNlbDoKKwkJCQkJCWxpbmVubyA9IGxpbmVzZWxbLTFdCisJCQkJCWVsaWYgc2VsZi53LnBhbmVzLmdyLmJyZWFrczoKKwkJCQkJCWxpbmVubyA9IHNlbGYudy5wYW5lcy5nci5icmVha3NbMF0KKwkJCQllZGl0b3IgPSBzZWxmLncuX3BhcmVudHdpbmRvdy5wYXJlbnQub3BlbnNjcmlwdChmaWxlbmFtZSwgbGluZW5vKQorCQkJCWVkaXRvci5zaG93YnJlYWtwb2ludHMoMSkKKwkJCXJldHVybgorCQlpZiBsZW4oc2VsKSA9PSAxOgorCQkJZmlsZSA9IHNlbFswXQorCQkJZmlsZWJyZWFrcyA9IHNlbGYuZGVidWdnZXIuYnJlYWtzW2ZpbGVdWzpdCisJCQlpZiBzZWxmLmN1cmZpbGUgPT0gZmlsZToKKwkJCQlsaW5lc2VsID0gc2VsZi53LnBhbmVzLmdyLmJyZWFrcy5nZXRzZWxlY3RlZG9iamVjdHMoKQorCQkJc2VsZi53LnBhbmVzLmdyLmJyZWFrcy5zZXQoZmlsZWJyZWFrcykKKwkJCWlmIHNlbGYuY3VyZmlsZSA9PSBmaWxlOgorCQkJCXNlbGYudy5wYW5lcy5nci5icmVha3Muc2V0c2VsZWN0ZWRvYmplY3RzKGxpbmVzZWwpCisJCQlzZWxmLmN1cmZpbGUgPSBmaWxlCisJCWVsc2U6CisJCQlpZiBsZW4oc2VsKSA8PiAwOgorCQkJCXNlbGYuY3VyZmlsZSA9IE5vbmUKKwkJCXNlbGYudy5wYW5lcy5nci5icmVha3Muc2V0KFtdKQorCQlzZWxmLmNoZWNrYnV0dG9ucygpCisJCisJZGVmIGxpbmVoaXQoc2VsZiwgaXNkYmwpOgorCQlpZiBpc2RibDoKKwkJCWZpbGVzID0gc2VsZi53LnBhbmVzLmZpbGVzLmdldHNlbGVjdGVkb2JqZWN0cygpCisJCQlpZiBsZW4oZmlsZXMpIDw+IDE6CisJCQkJcmV0dXJuCisJCQlmaWxlbmFtZSA9IGZpbGVzWzBdCisJCQlsaW5lbm9zID0gc2VsZi53LnBhbmVzLmdyLmJyZWFrcy5nZXRzZWxlY3RlZG9iamVjdHMoKQorCQkJaWYgbm90IGxpbmVub3M6CisJCQkJcmV0dXJuCisJCQlsaW5lbm8gPSBsaW5lbm9zWy0xXQorCQkJZWRpdG9yID0gc2VsZi53Ll9wYXJlbnR3aW5kb3cucGFyZW50Lm9wZW5zY3JpcHQoZmlsZW5hbWUsIGxpbmVubykKKwkJCWVkaXRvci5zaG93YnJlYWtwb2ludHMoMSkKKwkJc2VsZi5jaGVja2J1dHRvbnMoKQorCQorCWRlZiBjaGVja2J1dHRvbnMoc2VsZik6CisJCWlmIHNlbGYudy5wYW5lcy5maWxlcy5nZXRzZWxlY3Rpb24oKToKKwkJCXNlbGYudy5wYW5lcy5nci5vcGVuYnV0dG9uLmVuYWJsZSgxKQorCQkJc2VsZi53Ll9wYXJlbnR3aW5kb3cuc2V0ZGVmYXVsdGJ1dHRvbihzZWxmLncucGFuZXMuZ3Iub3BlbmJ1dHRvbikKKwkJCWlmIHNlbGYudy5fY3VycmVudHdpZGdldCA9PSBzZWxmLncucGFuZXMuZmlsZXM6CisJCQkJaWYgc2VsZi53LnBhbmVzLmZpbGVzLmdldHNlbGVjdGlvbigpOgorCQkJCQlzZWxmLncucGFuZXMuZ3IuZGVsZXRlYnV0dG9uLmVuYWJsZSgxKQorCQkJCWVsc2U6CisJCQkJCXNlbGYudy5wYW5lcy5nci5kZWxldGVidXR0b24uZW5hYmxlKDApCisJCQllbHNlOgorCQkJCWlmIHNlbGYudy5wYW5lcy5nci5icmVha3MuZ2V0c2VsZWN0aW9uKCk6CisJCQkJCXNlbGYudy5wYW5lcy5nci5kZWxldGVidXR0b24uZW5hYmxlKDEpCisJCQkJZWxzZToKKwkJCQkJc2VsZi53LnBhbmVzLmdyLmRlbGV0ZWJ1dHRvbi5lbmFibGUoMCkKKwkJZWxzZToKKwkJCXNlbGYudy5wYW5lcy5nci5vcGVuYnV0dG9uLmVuYWJsZSgwKQorCQkJc2VsZi53LnBhbmVzLmdyLmRlbGV0ZWJ1dHRvbi5lbmFibGUoMCkKKworCitjbGFzcyBUcmFjaW5nTW9uaXRvcihXLldpZGdldCk6CisJCisJZGVmIF9faW5pdF9fKHNlbGYsICphcmdzLCAqKmt3YXJncyk6CisJCWFwcGx5KFcuV2lkZ2V0Ll9faW5pdF9fLCAoc2VsZiwpICsgYXJncywga3dhcmdzKQorCQlzZWxmLnN0YXRlID0gMAorCQorCWRlZiB0b2dnbGUoc2VsZik6CisJCWlmIGhhc2F0dHIoc2VsZiwgIl9wYXJlbnR3aW5kb3ciKSBhbmQgc2VsZi5fcGFyZW50d2luZG93IGlzIG5vdCBOb25lOgorCQkJc2VsZi5zdGF0ZSA9IHNlbGYuc3RhdGUgJSAyICsgMQorCQkJcG9ydCA9IFFkLkdldFBvcnQoKQorCQkJc2VsZi5TZXRQb3J0KCkKKwkJCXNlbGYuZHJhdygpCisJCQlRZC5TZXRQb3J0KHBvcnQpCisJCisJZGVmIHJlc2V0KHNlbGYpOgorCQlpZiBzZWxmLl9wYXJlbnR3aW5kb3c6CisJCQlzZWxmLnN0YXRlID0gMAorCQkJcG9ydCA9IFFkLkdldFBvcnQoKQorCQkJc2VsZi5TZXRQb3J0KCkKKwkJCXNlbGYuZHJhdygpCisJCQlRZC5TZXRQb3J0KHBvcnQpCisJCisJZGVmIGRyYXcoc2VsZiwgdmlzUmduID0gTm9uZSk6CisJCWlmIHNlbGYuc3RhdGUgPT0gMjoKKwkJCVFkLlBhaW50T3ZhbChzZWxmLl9ib3VuZHMpCisJCWVsc2U6CisJCQlRZC5FcmFzZU92YWwoc2VsZi5fYm91bmRzKQorCisKKyMgY29udmVuaWVuY2UgZnVuY3MKKworZGVmIHBvc3Rtb3J0ZW0oZXhjX3R5cGUsIGV4Y192YWx1ZSwgdGIpOgorCWQgPSBnZXRkZWJ1Z2dlcigpCisJZC5wb3N0bW9ydGVtKGV4Y190eXBlLCBleGNfdmFsdWUsIHRiKQorCitkZWYgc3RhcnQoYm90dG9tZnJhbWUgPSBOb25lKToKKwlkID0gZ2V0ZGVidWdnZXIoKQorCWQuc3RhcnQoYm90dG9tZnJhbWUpCisKK2RlZiBzdGFydGZyb21oZXJlKCk6CisJZCA9IGdldGRlYnVnZ2VyKCkKKwl0cnk6CisJCXJhaXNlICdzcGFtJworCWV4Y2VwdDoKKwkJZnJhbWUgPSBzeXMuZXhjX3RyYWNlYmFjay50Yl9mcmFtZS5mX2JhY2sKKwlkLnN0YXJ0KGZyYW1lKQorCitkZWYgc3RhcnRmcm9tYm90dG9tKCk6CisJZCA9IGdldGRlYnVnZ2VyKCkKKwlkLnN0YXJ0KF9nZXRib3R0b21mcmFtZSgpLCAxKQorCitkZWYgc3RvcCgpOgorCWQgPSBnZXRkZWJ1Z2dlcigpCisJZC5zdG9wKCkKKworZGVmIGNvbnQoKToKKwlzeXMuc2V0dHJhY2UoTm9uZSkKKwlkID0gZ2V0ZGVidWdnZXIoKQorCWQuc2V0X2NvbnRpbnVlX3dpdGhvdXRfZGVidWdnZXIoKQorCitkZWYgX2dldGJvdHRvbWZyYW1lKCk6CisJdHJ5OgorCQlyYWlzZSAnc3BhbScKKwlleGNlcHQ6CisJCXBhc3MKKwlmcmFtZSA9IHN5cy5leGNfdHJhY2ViYWNrLnRiX2ZyYW1lCisJd2hpbGUgMToKKwkJaWYgZnJhbWUuZl9jb2RlLmNvX25hbWUgPT0gJ21haW5sb29wJyBvciBmcmFtZS5mX2JhY2sgaXMgTm9uZToKKwkJCWJyZWFrCisJCWZyYW1lID0gZnJhbWUuZl9iYWNrCisJcmV0dXJuIGZyYW1lCisKK19kZWJ1Z2dlciA9IE5vbmUKKworZGVmIGdldGRlYnVnZ2VyKCk6CisJZ2xvYmFsIF9kZWJ1Z2dlcgorCWlmIF9kZWJ1Z2dlciBpcyBOb25lOgorCQlfZGVidWdnZXIgPSBEZWJ1Z2dlcigpCisJcmV0dXJuIF9kZWJ1Z2dlcgpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1B5RWRpdC5weSBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9QeUVkaXQucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTBmOTJmZgotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9QeUVkaXQucHkKQEAgLTAsMCArMSw5NjMgQEAKKyIiImEgc2ltcGxlIHB5dGhvbiBlZGl0b3IiIiIKKworaW1wb3J0IFcKK2ltcG9ydCBXdHJhY2ViYWNrCitmcm9tIFNwZWNpYWxLZXlzIGltcG9ydCAqCisKK2ltcG9ydCBtYWNmcworaW1wb3J0IE1hY09TCitpbXBvcnQgV2luCitpbXBvcnQgUmVzCitpbXBvcnQgRXZ0CitpbXBvcnQgb3MKK2ltcG9ydCBpbXAKK2ltcG9ydCBzeXMKK2ltcG9ydCBzdHJpbmcKK2ltcG9ydCBtYXJzaGFsCitpbXBvcnQgcmVnZXgKKworX3NjcmlwdHVudGl0bGVkY291bnRlciA9IDEKK193b3JkY2hhcnMgPSBzdHJpbmcubGV0dGVycyArIHN0cmluZy5kaWdpdHMgKyAiXyIKKworCitjbGFzcyBFZGl0b3IoVy5XaW5kb3cpOgorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBwYXRoID0gIiIsIHRpdGxlID0gIiIpOgorCQlnbG9iYWwgX3NjcmlwdHVudGl0bGVkY291bnRlcgorCQlpZiBub3QgcGF0aDoKKwkJCWlmIHRpdGxlOgorCQkJCXNlbGYudGl0bGUgPSB0aXRsZQorCQkJZWxzZToKKwkJCQlzZWxmLnRpdGxlID0gIlVudGl0bGVkIFNjcmlwdCAiICsgYF9zY3JpcHR1bnRpdGxlZGNvdW50ZXJgCisJCQkJX3NjcmlwdHVudGl0bGVkY291bnRlciA9IF9zY3JpcHR1bnRpdGxlZGNvdW50ZXIgKyAxCisJCQl0ZXh0ID0gIiIKKwkJCXNlbGYuX2NyZWF0b3IgPSBXLl9zaWduYXR1cmUKKwkJZWxpZiBvcy5wYXRoLmV4aXN0cyhwYXRoKToKKwkJCXNlbGYudGl0bGUgPSBvcy5wYXRoLmJhc2VuYW1lKHBhdGgpCisJCQlmID0gb3BlbihwYXRoLCAicmIiKQorCQkJdGV4dCA9IGYucmVhZCgpCisJCQlmLmNsb3NlKCkKKwkJCWZzcyA9IG1hY2ZzLkZTU3BlYyhwYXRoKQorCQkJc2VsZi5fY3JlYXRvciwgZmlsZXR5cGUgPSBmc3MuR2V0Q3JlYXRvclR5cGUoKQorCQllbHNlOgorCQkJcmFpc2UgSU9FcnJvciwgImZpbGUgJyVzJyBkb2VzIG5vdCBleGlzdCIgJSBwYXRoCisJCXNlbGYucGF0aCA9IHBhdGgKKwkJCisJCXNlbGYuc2V0dGluZ3MgPSB7fQorCQlpZiBzZWxmLnBhdGg6CisJCQlzZWxmLnJlYWR3aW5kb3dzZXR0aW5ncygpCisJCWlmIHNlbGYuc2V0dGluZ3MuaGFzX2tleSgid2luZG93Ym91bmRzIik6CisJCQlib3VuZHMgPSBzZWxmLnNldHRpbmdzWyJ3aW5kb3dib3VuZHMiXQorCQllbHNlOgorCQkJYm91bmRzID0gKDUwMCwgMjUwKQorCQlpZiBzZWxmLnNldHRpbmdzLmhhc19rZXkoImZvbnRzZXR0aW5ncyIpOgorCQkJc2VsZi5mb250c2V0dGluZ3MgPSBzZWxmLnNldHRpbmdzWyJmb250c2V0dGluZ3MiXQorCQllbHNlOgorCQkJc2VsZi5mb250c2V0dGluZ3MgPSAoIlB5dGhvbi1TYW5zIiwgMCwgOSwgKDAsIDAsIDApKQorCQlXLldpbmRvdy5fX2luaXRfXyhzZWxmLCBib3VuZHMsIHNlbGYudGl0bGUsIG1pbnNpemUgPSAoMzMwLCAxMjApLCB0YWJiYWJsZSA9IDApCisJCQorCQlzZWxmLnNldHVwd2lkZ2V0cyh0ZXh0KQorCQlpZiBzZWxmLnNldHRpbmdzLmhhc19rZXkoInNlbGVjdGlvbiIpOgorCQkJc2Vsc3RhcnQsIHNlbGVuZCA9IHNlbGYuc2V0dGluZ3NbInNlbGVjdGlvbiJdCisJCQlzZWxmLnNldHNlbGVjdGlvbihzZWxzdGFydCwgc2VsZW5kKQorCQlzZWxmLm9wZW4oKQorCQlzZWxmLnNldGluZm90ZXh0KCkKKwkJc2VsZi5nbG9iYWxzID0ge30KKwkJc2VsZi5fYnVmID0gIiIgICMgZm9yIHdyaXRlIG1ldGhvZAorCQlzZWxmLmRlYnVnZ2luZyA9IDAKKwkJc2VsZi5wcm9maWxpbmcgPSAwCisJCWlmIHNlbGYuc2V0dGluZ3MuaGFzX2tleSgicnVuX2FzX21haW4iKToKKwkJCXNlbGYucnVuX2FzX21haW4gPSBzZWxmLnNldHRpbmdzWyJydW5fYXNfbWFpbiJdCisJCWVsc2U6CisJCQlzZWxmLnJ1bl9hc19tYWluID0gMAorCQorCWRlZiByZWFkd2luZG93c2V0dGluZ3Moc2VsZik6CisJCXRyeToKKwkJCXJlc3JlZiA9IFJlcy5PcGVuUmVzRmlsZShzZWxmLnBhdGgpCisJCWV4Y2VwdCBSZXMuRXJyb3I6CisJCQlyZXR1cm4KKwkJdHJ5OgorCQkJUmVzLlVzZVJlc0ZpbGUocmVzcmVmKQorCQkJZGF0YSA9IFJlcy5HZXQxUmVzb3VyY2UoJ1B5V1MnLCAxMjgpCisJCQlzZWxmLnNldHRpbmdzID0gbWFyc2hhbC5sb2FkcyhkYXRhLmRhdGEpCisJCWV4Y2VwdDoKKwkJCXBhc3MKKwkJUmVzLkNsb3NlUmVzRmlsZShyZXNyZWYpCisJCQorCWRlZiB3cml0ZXdpbmRvd3NldHRpbmdzKHNlbGYpOgorCQl0cnk6CisJCQlyZXNyZWYgPSBSZXMuT3BlblJlc0ZpbGUoc2VsZi5wYXRoKQorCQlleGNlcHQgUmVzLkVycm9yOgorCQkJUmVzLkNyZWF0ZVJlc0ZpbGUoc2VsZi5wYXRoKQorCQkJcmVzcmVmID0gUmVzLk9wZW5SZXNGaWxlKHNlbGYucGF0aCkKKwkJdHJ5OgorCQkJZGF0YSA9IFJlcy5SZXNvdXJjZShtYXJzaGFsLmR1bXBzKHNlbGYuc2V0dGluZ3MpKQorCQkJUmVzLlVzZVJlc0ZpbGUocmVzcmVmKQorCQkJdHJ5OgorCQkJCXRlbXAgPSBSZXMuR2V0MVJlc291cmNlKCdQeVdTJywgMTI4KQorCQkJCXRlbXAuUmVtb3ZlUmVzb3VyY2UoKQorCQkJZXhjZXB0IFJlcy5FcnJvcjoKKwkJCQlwYXNzCisJCQlkYXRhLkFkZFJlc291cmNlKCdQeVdTJywgMTI4LCAid2luZG93IHNldHRpbmdzIikKKwkJZmluYWxseToKKwkJCVJlcy5VcGRhdGVSZXNGaWxlKHJlc3JlZikKKwkJCVJlcy5DbG9zZVJlc0ZpbGUocmVzcmVmKQorCQorCWRlZiBnZXRzZXR0aW5ncyhzZWxmKToKKwkJc2VsZi5zZXR0aW5ncyA9IHt9CisJCXNlbGYuc2V0dGluZ3NbIndpbmRvd2JvdW5kcyJdID0gc2VsZi5nZXRib3VuZHMoKQorCQlzZWxmLnNldHRpbmdzWyJzZWxlY3Rpb24iXSA9IHNlbGYuZ2V0c2VsZWN0aW9uKCkKKwkJc2VsZi5zZXR0aW5nc1siZm9udHNldHRpbmdzIl0gPSBzZWxmLmVkaXRncm91cC5lZGl0b3IuZ2V0Zm9udHNldHRpbmdzKCkKKwkJc2VsZi5zZXR0aW5nc1sicnVuX2FzX21haW4iXSA9IHNlbGYucnVuX2FzX21haW4KKwkKKwlkZWYgZ2V0KHNlbGYpOgorCQlyZXR1cm4gc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmdldCgpCisJCisJZGVmIGdldHNlbGVjdGlvbihzZWxmKToKKwkJcmV0dXJuIHNlbGYuZWRpdGdyb3VwLmVkaXRvci50ZWQuV0VHZXRTZWxlY3Rpb24oKQorCQorCWRlZiBzZXRzZWxlY3Rpb24oc2VsZiwgc2Vsc3RhcnQsIHNlbGVuZCk6CisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5zZXRzZWxlY3Rpb24oc2Vsc3RhcnQsIHNlbGVuZCkKKwkKKwlkZWYgZ2V0ZmlsZW5hbWUoc2VsZik6CisJCWlmIHNlbGYucGF0aDoKKwkJCXJldHVybiBzZWxmLnBhdGgKKwkJcmV0dXJuICc8JXM+JyAlIHNlbGYudGl0bGUKKwkKKwlkZWYgc2V0dXB3aWRnZXRzKHNlbGYsIHRleHQpOgorCQl0b3BiYXJoZWlnaHQgPSAyNAorCQlwb3BmaWVsZHdpZHRoID0gODAKKwkJc2VsZi5sYXN0bGluZW5vID0gTm9uZQorCQkKKwkJIyBtYWtlIGFuIGVkaXRvcgorCQlzZWxmLmVkaXRncm91cCA9IFcuR3JvdXAoKDAsIHRvcGJhcmhlaWdodCArIDEsIDAsIDApKQorCQllZGl0b3IgPSBXLlB5RWRpdG9yKCgwLCAwLCAtMTUsLTE1KSwgdGV4dCwgZm9udHNldHRpbmdzID0gc2VsZi5mb250c2V0dGluZ3MsIAorCQkJCWZpbGUgPSBzZWxmLmdldGZpbGVuYW1lKCkpCisJCQorCQkjIG1ha2UgdGhlIHdpZGdldHMKKwkJc2VsZi5wb3BmaWVsZCA9IENsYXNzRmluZGVyKChwb3BmaWVsZHdpZHRoIC0gMTcsIC0xNSwgMTYsIDE2KSwgW10sIHNlbGYucG9wc2VsZWN0bGluZSkKKwkJc2VsZi5saW5lZmllbGQgPSBXLkVkaXRUZXh0KCgtMSwgLTE1LCBwb3BmaWVsZHdpZHRoIC0gMTUsIDE2KSwgaW5zZXQgPSAoNiwgMikpCisJCXNlbGYuZWRpdGdyb3VwLl9iYXJ4ID0gVy5TY3JvbGxiYXIoKHBvcGZpZWxkd2lkdGggLSAyLCAtMTUsIC0xNCwgMTYpLCBlZGl0b3IuaHNjcm9sbCwgbWF4ID0gMzI3NjcpCisJCXNlbGYuZWRpdGdyb3VwLl9iYXJ5ID0gVy5TY3JvbGxiYXIoKC0xNSwgMTQsIDE2LCAtMTQpLCBlZGl0b3IudnNjcm9sbCwgbWF4ID0gMzI3NjcpCisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvciA9IGVkaXRvcgkjIGFkZCBlZGl0b3IgKmFmdGVyKiBzY3JvbGxiYXJzCisJCQorCQlzZWxmLmVkaXRncm91cC5vcHRpb25zbWVudSA9IFcuUG9wdXBNZW51KCgtMTUsIC0xLCAxNiwgMTYpLCBbXSkKKwkJc2VsZi5lZGl0Z3JvdXAub3B0aW9uc21lbnUuYmluZCgnPGNsaWNrPicsIHNlbGYubWFrZW9wdGlvbnNtZW51KQorCQlzZWxmLmhsaW5lID0gVy5Ib3Jpem9udGFsTGluZSgoMCwgdG9wYmFyaGVpZ2h0LCAwLCAwKSkKKwkJc2VsZi5pbmZvdGV4dCA9IFcuVGV4dEJveCgoMTc1LCA2LCAtNCwgMTQpKQorCQlzZWxmLnJ1bmJ1dHRvbiA9IFcuQnV0dG9uKCg1LCA0LCA4MCwgMTYpLCAiUnVuIGFsbCIsIHNlbGYucnVuKQorCQlzZWxmLnJ1bnNlbGJ1dHRvbiA9IFcuQnV0dG9uKCg5MCwgNCwgODAsIDE2KSwgIlJ1biBzZWxlY3Rpb24iLCBzZWxmLnJ1bnNlbGVjdGlvbikKKwkJCisJCSMgYmluZCBzb21lIGtleXMKKwkJZWRpdG9yLmJpbmQoImNtZHIiLCBzZWxmLnJ1bmJ1dHRvbi5wdXNoKQorCQllZGl0b3IuYmluZCgiZW50ZXIiLCBzZWxmLnJ1bnNlbGJ1dHRvbi5wdXNoKQorCQllZGl0b3IuYmluZCgiY21kaiIsIHNlbGYuZG9tZW51X2dvdG9saW5lKQorCQllZGl0b3IuYmluZCgiY21kZCIsIHNlbGYuZG9tZW51X3RvZ2dsZWRlYnVnZ2VyKQorCQllZGl0b3IuYmluZCgiPGlkbGU+Iiwgc2VsZi51cGRhdGVzZWxlY3Rpb24pCisJCQorCQllZGl0b3IuYmluZCgiY21kZSIsIHNlYXJjaGVuZ2luZS5zZXRmaW5kc3RyaW5nKQorCQllZGl0b3IuYmluZCgiY21kZiIsIHNlYXJjaGVuZ2luZS5zaG93KQorCQllZGl0b3IuYmluZCgiY21kZyIsIHNlYXJjaGVuZ2luZS5maW5kbmV4dCkKKwkJZWRpdG9yLmJpbmQoImNtZHNoaWZ0ciIsIHNlYXJjaGVuZ2luZS5yZXBsYWNlKQorCQllZGl0b3IuYmluZCgiY21kdCIsIHNlYXJjaGVuZ2luZS5yZXBsYWNlZmluZCkKKwkJCisJCXNlbGYubGluZWZpZWxkLmJpbmQoInJldHVybiIsIHNlbGYuZG9saW5lZmllbGQpCisJCXNlbGYubGluZWZpZWxkLmJpbmQoImVudGVyIiwgc2VsZi5kb2xpbmVmaWVsZCkKKwkJc2VsZi5saW5lZmllbGQuYmluZCgidGFiIiwgc2VsZi5kb2xpbmVmaWVsZCkKKwkJCisJCSMgaW50ZXJjZXB0IGNsaWNrcworCQllZGl0b3IuYmluZCgiPGNsaWNrPiIsIHNlbGYuY2xpY2tlZGl0b3IpCisJCXNlbGYubGluZWZpZWxkLmJpbmQoIjxjbGljaz4iLCBzZWxmLmNsaWNrbGluZWZpZWxkKQorCQorCWRlZiBtYWtlb3B0aW9uc21lbnUoc2VsZik6CisJCW1lbnVpdGVtcyA9IFsoJ0ZvbnQgc2V0dGluZ3OKJywgc2VsZi5kb21lbnVfZm9udHNldHRpbmdzKSwgCisJCQkJKCdcMCcgKyBjaHIoc2VsZi5ydW5fYXNfbWFpbikgKyAnUnVuIGFzIF9fbWFpbl9fJywgc2VsZi5kb21lbnVfdG9nZ2xlX3J1bl9hc19tYWluKSwgCisJCQkJKCdNb2R1bGFyaXplJywgc2VsZi5kb21lbnVfbW9kdWxhcml6ZSksCisJCQkJKCdCcm93c2UgbmFtZXNwYWNliicsIHNlbGYuZG9tZW51X2Jyb3dzZW5hbWVzcGFjZSksIAorCQkJCSctJ10KKwkJaWYgc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLl9kZWJ1Z2dlcjoKKwkJCW1lbnVpdGVtcyA9IG1lbnVpdGVtcyArIFsoJ0Rpc2FibGUgZGVidWdnZXInLCBzZWxmLmRvbWVudV90b2dnbGVkZWJ1Z2dlciksCisJCQkJKCdDbGVhciBicmVha3BvaW50cycsIHNlbGYuZG9tZW51X2NsZWFyYnJlYWtwb2ludHMpLAorCQkJCSgnRWRpdCBicmVha3BvaW50c4onLCBzZWxmLmRvbWVudV9lZGl0YnJlYWtwb2ludHMpXQorCQllbHNlOgorCQkJbWVudWl0ZW1zID0gbWVudWl0ZW1zICsgWygnRW5hYmxlIGRlYnVnZ2VyJywgc2VsZi5kb21lbnVfdG9nZ2xlZGVidWdnZXIpXQorCQlpZiBzZWxmLnByb2ZpbGluZzoKKwkJCW1lbnVpdGVtcyA9IG1lbnVpdGVtcyArIFsoJ0Rpc2FibGUgcHJvZmlsZXInLCBzZWxmLmRvbWVudV90b2dnbGVwcm9maWxlcildCisJCWVsc2U6CisJCQltZW51aXRlbXMgPSBtZW51aXRlbXMgKyBbKCdFbmFibGUgcHJvZmlsZXInLCBzZWxmLmRvbWVudV90b2dnbGVwcm9maWxlcildCisJCXNlbGYuZWRpdGdyb3VwLm9wdGlvbnNtZW51LnNldChtZW51aXRlbXMpCisJCisJZGVmIGRvbWVudV90b2dnbGVfcnVuX2FzX21haW4oc2VsZik6CisJCXNlbGYucnVuX2FzX21haW4gPSBub3Qgc2VsZi5ydW5fYXNfbWFpbgorCQlzZWxmLmVkaXRncm91cC5lZGl0b3Iuc2VsY2hhbmdlZCA9IDEKKwkKKwlkZWYgc2hvd2JyZWFrcG9pbnRzKHNlbGYsIG9ub2ZmKToKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnNob3dicmVha3BvaW50cyhvbm9mZikKKwkJc2VsZi5kZWJ1Z2dpbmcgPSBvbm9mZgorCQorCWRlZiBkb21lbnVfY2xlYXJicmVha3BvaW50cyhzZWxmLCAqYXJncyk6CisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5jbGVhcmJyZWFrcG9pbnRzKCkKKwkKKwlkZWYgZG9tZW51X2VkaXRicmVha3BvaW50cyhzZWxmLCAqYXJncyk6CisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5lZGl0YnJlYWtwb2ludHMoKQorCQorCWRlZiBkb21lbnVfdG9nZ2xlZGVidWdnZXIoc2VsZiwgKmFyZ3MpOgorCQlpZiBub3Qgc2VsZi5kZWJ1Z2dpbmc6CisJCQlXLlNldEN1cnNvcignd2F0Y2gnKQorCQlzZWxmLmRlYnVnZ2luZyA9IG5vdCBzZWxmLmRlYnVnZ2luZworCQlzZWxmLmVkaXRncm91cC5lZGl0b3IudG9nZ2xlYnJlYWtwb2ludHMoKQorCQkKKwlkZWYgZG9tZW51X3RvZ2dsZXByb2ZpbGVyKHNlbGYsICphcmdzKToKKwkJc2VsZi5wcm9maWxpbmcgPSBub3Qgc2VsZi5wcm9maWxpbmcKKwkKKwlkZWYgZG9tZW51X2Jyb3dzZW5hbWVzcGFjZShzZWxmLCAqYXJncyk6CisJCWltcG9ydCBQeUJyb3dzZXIsIFcKKwkJVy5TZXRDdXJzb3IoJ3dhdGNoJykKKwkJZ2xvYmFscywgZmlsZSA9IHNlbGYuZ2V0ZW52aXJvbm1lbnQoKQorCQltb2RuYW1lID0gX2ZpbGVuYW1lX2FzX21vZG5hbWUoc2VsZi50aXRsZSkKKwkJaWYgbm90IG1vZG5hbWU6CisJCQltb2RuYW1lID0gc2VsZi50aXRsZQorCQlQeUJyb3dzZXIuQnJvd3NlcihnbG9iYWxzLCAiT2JqZWN0IGJyb3dzZXI6ICIgKyBtb2RuYW1lKQorCQorCWRlZiBkb21lbnVfbW9kdWxhcml6ZShzZWxmLCAqYXJncyk6CisJCW1vZG5hbWUgPSBfZmlsZW5hbWVfYXNfbW9kbmFtZShzZWxmLnRpdGxlKQorCQlpZiBub3QgbW9kbmFtZToKKwkJCXJhaXNlIFcuQWxlcnRFcnJvciwgJ0Nhbrl0IG1vZHVsYXJpemUgsyVzsicgJSBzZWxmLnRpdGxlCisJCXNlbGYucnVuKCkJCisJCWlmIHNlbGYucGF0aDoKKwkJCWZpbGUgPSBzZWxmLnBhdGgKKwkJZWxzZToKKwkJCWZpbGUgPSBzZWxmLnRpdGxlCisJCQorCQlpZiBzZWxmLmdsb2JhbHMgYW5kIG5vdCBzeXMubW9kdWxlcy5oYXNfa2V5KG1vZG5hbWUpOgorCQkJbW9kdWxlID0gaW1wLm5ld19tb2R1bGUobW9kbmFtZSkKKwkJCWZvciBhdHRyIGluIHNlbGYuZ2xvYmFscy5rZXlzKCk6CisJCQkJc2V0YXR0cihtb2R1bGUsYXR0cixzZWxmLmdsb2JhbHNbYXR0cl0pCisJCQlzeXMubW9kdWxlc1ttb2RuYW1lXSA9IG1vZHVsZQorCQkJc2VsZi5nbG9iYWxzID0ge30KKwkKKwlkZWYgZG9tZW51X2ZvbnRzZXR0aW5ncyhzZWxmLCAqYXJncyk6CisJCWltcG9ydCBGb250U2V0dGluZ3MKKwkJZm9udHNldHRpbmdzID0gRm9udFNldHRpbmdzLkZvbnREaWFsb2coc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmdldGZvbnRzZXR0aW5ncygpKQorCQlpZiBmb250c2V0dGluZ3M6CisJCQlzZWxmLmVkaXRncm91cC5lZGl0b3Iuc2V0Zm9udHNldHRpbmdzKGZvbnRzZXR0aW5ncykKKwkKKwlkZWYgY2xpY2tsaW5lZmllbGQoc2VsZik6CisJCWlmIHNlbGYuX2N1cnJlbnR3aWRnZXQgPD4gc2VsZi5saW5lZmllbGQ6CisJCQlzZWxmLmxpbmVmaWVsZC5zZWxlY3QoMSkKKwkJCXNlbGYubGluZWZpZWxkLnNlbGVjdGFsbCgpCisJCQlyZXR1cm4gMQorCQorCWRlZiBjbGlja2VkaXRvcihzZWxmKToKKwkJaWYgc2VsZi5fY3VycmVudHdpZGdldCA8PiBzZWxmLmVkaXRncm91cC5lZGl0b3I6CisJCQlzZWxmLmRvbGluZWZpZWxkKCkKKwkJCXJldHVybiAxCisJCisJZGVmIHVwZGF0ZXNlbGVjdGlvbihzZWxmLCBmb3JjZSA9IDApOgorCQlzZWwgPSBtaW4oc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmdldHNlbGVjdGlvbigpKQorCQlsaW5lbm8gPSBzZWxmLmVkaXRncm91cC5lZGl0b3Iub2Zmc2V0dG9saW5lKHNlbCkKKwkJaWYgbGluZW5vIDw+IHNlbGYubGFzdGxpbmVubyBvciBmb3JjZToKKwkJCXNlbGYubGFzdGxpbmVubyA9IGxpbmVubworCQkJc2VsZi5saW5lZmllbGQuc2V0KHN0cihsaW5lbm8gKyAxKSkKKwkJCXNlbGYubGluZWZpZWxkLnNlbHZpZXcoKQorCQorCWRlZiBkb2xpbmVmaWVsZChzZWxmKToKKwkJdHJ5OgorCQkJbGluZW5vID0gc3RyaW5nLmF0b2koc2VsZi5saW5lZmllbGQuZ2V0KCkpIC0gMQorCQkJaWYgbGluZW5vIDw+IHNlbGYubGFzdGxpbmVubzoKKwkJCQlzZWxmLmVkaXRncm91cC5lZGl0b3Iuc2VsZWN0bGluZShsaW5lbm8pCisJCQkJc2VsZi51cGRhdGVzZWxlY3Rpb24oMSkKKwkJZXhjZXB0OgorCQkJc2VsZi51cGRhdGVzZWxlY3Rpb24oMSkKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnNlbGVjdCgxKQorCQorCWRlZiBzZXRpbmZvdGV4dChzZWxmKToKKwkJaWYgbm90IGhhc2F0dHIoc2VsZiwgJ2luZm90ZXh0Jyk6CisJCQlyZXR1cm4KKwkJaWYgc2VsZi5wYXRoOgorCQkJc2VsZi5pbmZvdGV4dC5zZXQoc2VsZi5wYXRoKQorCQllbHNlOgorCQkJc2VsZi5pbmZvdGV4dC5zZXQoIiIpCisJCisJZGVmIGNsb3NlKHNlbGYpOgorCQlpZiBzZWxmLmVkaXRncm91cC5lZGl0b3IuY2hhbmdlZDoKKwkJCWltcG9ydCBFYXN5RGlhbG9ncworCQkJaW1wb3J0IFFkCisJCQlRZC5Jbml0Q3Vyc29yKCkgIyBYWFggc2hvdWxkIGJlIGRvbmUgYnkgZGlhbG9nCisJCQlzYXZlID0gRWFzeURpYWxvZ3MuQXNrWWVzTm9DYW5jZWwoJ1NhdmUgd2luZG93ILMlc7IgYmVmb3JlIGNsb3Npbmc/JyAlIHNlbGYudGl0bGUsIDEpCisJCQlpZiBzYXZlID4gMDoKKwkJCQlpZiBzZWxmLmRvbWVudV9zYXZlKCk6CisJCQkJCXJldHVybiAxCisJCQllbGlmIHNhdmUgPCAwOgorCQkJCXJldHVybiAxCisJCXNlbGYuZ2xvYmFscyA9IE5vbmUJICAgICAjIFhYWCBkb2Vzbid0IGhlbHAuLi4gYWxsIGdsb2JhbHMgbGVhayA6LSgKKwkJVy5XaW5kb3cuY2xvc2Uoc2VsZikKKwkKKwlkZWYgZG9tZW51X2Nsb3NlKHNlbGYsICphcmdzKToKKwkJcmV0dXJuIHNlbGYuY2xvc2UoKQorCQorCWRlZiBkb21lbnVfc2F2ZShzZWxmLCAqYXJncyk6CisJCWlmIG5vdCBzZWxmLnBhdGg6CisJCQkjIFdpbGwgY2FsbCB1cyByZWN1cnNpdmVseQorCQkJcmV0dXJuIHNlbGYuZG9tZW51X3NhdmVfYXMoKQorCQlkYXRhID0gc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmdldCgpCisJCWZwID0gb3BlbihzZWxmLnBhdGgsICd3YicpICAjIG9wZW4gZmlsZSBpbiBiaW5hcnkgbW9kZSwgZGF0YSBoYXMgJ1xyJyBsaW5lLWVuZGluZ3MKKwkJZnAud3JpdGUoZGF0YSkKKwkJZnAuY2xvc2UoKQorCQlmc3MgPSBtYWNmcy5GU1NwZWMoc2VsZi5wYXRoKQorCQlmc3MuU2V0Q3JlYXRvclR5cGUoc2VsZi5fY3JlYXRvciwgJ1RFWFQnKQorCQlzZWxmLmdldHNldHRpbmdzKCkKKwkJc2VsZi53cml0ZXdpbmRvd3NldHRpbmdzKCkKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmNoYW5nZWQgPSAwCisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5zZWxjaGFuZ2VkID0gMAorCQlpbXBvcnQgbGluZWNhY2hlCisJCWlmIGxpbmVjYWNoZS5jYWNoZS5oYXNfa2V5KHNlbGYucGF0aCk6CisJCQlkZWwgbGluZWNhY2hlLmNhY2hlW3NlbGYucGF0aF0KKwkJaW1wb3J0IG1hY29zdG9vbHMKKwkJbWFjb3N0b29scy50b3VjaGVkKHNlbGYucGF0aCkKKwkKKwlkZWYgY2FuX3NhdmUoc2VsZiwgbWVudWl0ZW0pOgorCQlyZXR1cm4gc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmNoYW5nZWQgb3Igc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnNlbGNoYW5nZWQKKwkKKwlkZWYgZG9tZW51X3NhdmVfYXMoc2VsZiwgKmFyZ3MpOgorCQlmc3MsIG9rID0gbWFjZnMuU3RhbmRhcmRQdXRGaWxlKCdTYXZlIGFzOicsIHNlbGYudGl0bGUpCisJCWlmIG5vdCBvazogCisJCQlyZXR1cm4gMQorCQlzZWxmLnNob3dicmVha3BvaW50cygwKQorCQlzZWxmLnBhdGggPSBmc3MuYXNfcGF0aG5hbWUoKQorCQlzZWxmLnNldGluZm90ZXh0KCkKKwkJc2VsZi50aXRsZSA9IG9zLnBhdGguc3BsaXQoc2VsZi5wYXRoKVstMV0KKwkJc2VsZi53aWQuU2V0V1RpdGxlKHNlbGYudGl0bGUpCisJCXNlbGYuZG9tZW51X3NhdmUoKQorCQlzZWxmLmVkaXRncm91cC5lZGl0b3Iuc2V0ZmlsZShzZWxmLmdldGZpbGVuYW1lKCkpCisJCWFwcCA9IFcuZ2V0YXBwbGljYXRpb24oKQorCQlhcHAubWFrZW9wZW53aW5kb3dzbWVudSgpCisJCWlmIGhhc2F0dHIoYXBwLCAnbWFrZXNjcmlwdHNtZW51Jyk6CisJCQlhcHAgPSBXLmdldGFwcGxpY2F0aW9uKCkKKwkJCWZzcywgZnNzX2NoYW5nZWQgPSBhcHAuc2NyaXB0c2ZvbGRlci5SZXNvbHZlKCkKKwkJCXBhdGggPSBmc3MuYXNfcGF0aG5hbWUoKQorCQkJaWYgcGF0aCA9PSBzZWxmLnBhdGhbOmxlbihwYXRoKV06CisJCQkJVy5nZXRhcHBsaWNhdGlvbigpLm1ha2VzY3JpcHRzbWVudSgpCisJCisJZGVmIGRvbWVudV9nb3RvbGluZShzZWxmLCAqYXJncyk6CisJCXNlbGYubGluZWZpZWxkLnNlbGVjdGFsbCgpCisJCXNlbGYubGluZWZpZWxkLnNlbGVjdCgxKQorCQlzZWxmLmxpbmVmaWVsZC5zZWxlY3RhbGwoKQorCQorCWRlZiBkb21lbnVfc2VsZWN0bGluZShzZWxmLCAqYXJncyk6CisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5leHBhbmRzZWxlY3Rpb24oKQorCQorCWRlZiBkb21lbnVfc2hpZnRsZWZ0KHNlbGYsICphcmdzKToKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnNoaWZ0bGVmdCgpCisJCisJZGVmIGRvbWVudV9zaGlmdHJpZ2h0KHNlbGYsICphcmdzKToKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnNoaWZ0cmlnaHQoKQorCQorCWRlZiBkb21lbnVfZmluZChzZWxmLCAqYXJncyk6CisJCXNlYXJjaGVuZ2luZS5zaG93KCkKKwkKKwlkZWYgZG9tZW51X2VudGVyc2VhcmNoc3RyaW5nKHNlbGYsICphcmdzKToKKwkJc2VhcmNoZW5naW5lLnNldGZpbmRzdHJpbmcoKQorCQorCWRlZiBkb21lbnVfcmVwbGFjZShzZWxmLCAqYXJncyk6CisJCXNlYXJjaGVuZ2luZS5yZXBsYWNlKCkKKwkKKwlkZWYgZG9tZW51X2ZpbmRuZXh0KHNlbGYsICphcmdzKToKKwkJc2VhcmNoZW5naW5lLmZpbmRuZXh0KCkKKwkKKwlkZWYgZG9tZW51X3JlcGxhY2VmaW5kKHNlbGYsICphcmdzKToKKwkJc2VhcmNoZW5naW5lLnJlcGxhY2VmaW5kKCkKKwkKKwlkZWYgZG9tZW51X3J1bihzZWxmLCAqYXJncyk6CisJCXNlbGYucnVuYnV0dG9uLnB1c2goKQorCQorCWRlZiBkb21lbnVfcnVuc2VsZWN0aW9uKHNlbGYsICphcmdzKToKKwkJc2VsZi5ydW5zZWxidXR0b24ucHVzaCgpCisJCisJZGVmIHJ1bihzZWxmKToKKwkJcHl0ZXh0ID0gc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmdldCgpCisJCWdsb2JhbHMsIGZpbGUgPSBzZWxmLmdldGVudmlyb25tZW50KCkKKwkJaWYgc2VsZi5wYXRoOgorCQkJY3dkID0gb3MuZ2V0Y3dkKCkKKwkJCW9zLmNoZGlyKG9zLnBhdGguZGlybmFtZShzZWxmLnBhdGgpICsgJzonKQorCQllbHNlOgorCQkJY3dkID0gTm9uZQorCQlleGVjc3RyaW5nKHB5dGV4dCwgZ2xvYmFscywgZ2xvYmFscywgZmlsZSwgc2VsZi5kZWJ1Z2dpbmcsIHNlbGYucnVuX2FzX21haW4sIHNlbGYucHJvZmlsaW5nKQorCQlpZiBjd2Q6CisJCQlvcy5jaGRpcihjd2QpCisJCisJZGVmIHJ1bnNlbGVjdGlvbihzZWxmKToKKwkJc2VsZi5fcnVuc2VsZWN0aW9uKCkKKwkKKwlkZWYgX3J1bnNlbGVjdGlvbihzZWxmKToKKwkJZ2xvYmFscywgZmlsZSA9IHNlbGYuZ2V0ZW52aXJvbm1lbnQoKQorCQlsb2NhbHMgPSBnbG9iYWxzCisJCSMgc2VsZWN0IHdob2xlIGxpbmVzCisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5leHBhbmRzZWxlY3Rpb24oKQorCQkKKwkJIyBnZXQgbGluZW5vIG9mIGZpcnN0IHNlbGVjdGVkIGxpbmUKKwkJc2Vsc3RhcnQsIHNlbGVuZCA9IHNlbGYuZWRpdGdyb3VwLmVkaXRvci5nZXRzZWxlY3Rpb24oKQorCQlzZWxzdGFydCwgc2VsZW5kID0gbWluKHNlbHN0YXJ0LCBzZWxlbmQpLCBtYXgoc2Vsc3RhcnQsIHNlbGVuZCkKKwkJc2VsZmlyc3RsaW5lID0gc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLm9mZnNldHRvbGluZShzZWxzdGFydCkKKwkJYWxsdGV4dCA9IHNlbGYuZWRpdGdyb3VwLmVkaXRvci5nZXQoKQorCQlweXRleHQgPSBhbGx0ZXh0W3NlbHN0YXJ0OnNlbGVuZF0KKwkJbGluZXMgPSBzdHJpbmcuc3BsaXQocHl0ZXh0LCAnXHInKQorCQlpbmRlbnQgPSBnZXRtaW5pbmRlbnQobGluZXMpCisJCWlmIGluZGVudCA9PSAxOgorCQkJY2xhc3NuYW1lID0gJycKKwkJCWFsbGxpbmVzID0gc3RyaW5nLnNwbGl0KGFsbHRleHQsICdccicpCisJCQlpZGVudGlmaWVSRV9tYXRjaCA9IF9pZGVudGlmaWVSRS5tYXRjaAorCQkJZm9yIGkgaW4gcmFuZ2Uoc2VsZmlyc3RsaW5lIC0gMSwgLTEsIC0xKToKKwkJCQlsaW5lID0gYWxsbGluZXNbaV0KKwkJCQlpZiBsaW5lWzo2XSA9PSAnY2xhc3MgJzoKKwkJCQkJY2xhc3NuYW1lID0gc3RyaW5nLnNwbGl0KHN0cmluZy5zdHJpcChsaW5lWzY6XSkpWzBdCisJCQkJCWNsYXNzZW5kID0gaWRlbnRpZmllUkVfbWF0Y2goY2xhc3NuYW1lKQorCQkJCQlpZiBjbGFzc2VuZCA8IDE6CisJCQkJCQlyYWlzZSBXLkFsZXJ0RXJyb3IsICdDYW65dCBmaW5kIGEgY2xhc3MuJworCQkJCQljbGFzc25hbWUgPSBjbGFzc25hbWVbOmNsYXNzZW5kXQorCQkJCQlicmVhaworCQkJCWVsaWYgbGluZSBhbmQgbGluZVswXSBub3QgaW4gJ1x0Iyc6CisJCQkJCXJhaXNlIFcuQWxlcnRFcnJvciwgJ0Nhbrl0IGZpbmQgYSBjbGFzcy4nCisJCQllbHNlOgorCQkJCXJhaXNlIFcuQWxlcnRFcnJvciwgJ0Nhbrl0IGZpbmQgYSBjbGFzcy4nCisJCQlpZiBnbG9iYWxzLmhhc19rZXkoY2xhc3NuYW1lKToKKwkJCQlsb2NhbHMgPSBnbG9iYWxzW2NsYXNzbmFtZV0uX19kaWN0X18KKwkJCWVsc2U6CisJCQkJcmFpc2UgVy5BbGVydEVycm9yLCAnQ2FuuXQgZmluZCBjbGFzcyCzJXOyLicgJSBjbGFzc25hbWUKKwkJCWZvciBpIGluIHJhbmdlKGxlbihsaW5lcykpOgorCQkJCWxpbmVzW2ldID0gbGluZXNbaV1bMTpdCisJCQlweXRleHQgPSBzdHJpbmcuam9pbihsaW5lcywgJ1xyJykKKwkJZWxpZiBpbmRlbnQgPiAwOgorCQkJcmFpc2UgVy5BbGVydEVycm9yLCAnQ2FuuXQgcnVuIGluZGVudGVkIGNvZGUuJworCQkKKwkJIyBhZGQgbmV3bGluZXMgdG8gZm9vbCBjb21waWxlL2V4ZWM6IGEgdHJhY2ViYWNrIHdpbGwgZ2l2ZSB0aGUgcmlnaHQgbGluZSBudW1iZXIKKwkJcHl0ZXh0ID0gc2VsZmlyc3RsaW5lICogJ1xyJyArIHB5dGV4dAorCQkKKwkJaWYgc2VsZi5wYXRoOgorCQkJY3dkID0gb3MuZ2V0Y3dkKCkKKwkJCW9zLmNoZGlyKG9zLnBhdGguZGlybmFtZShzZWxmLnBhdGgpICsgJzonKQorCQllbHNlOgorCQkJY3dkID0gTm9uZQorCQlleGVjc3RyaW5nKHB5dGV4dCwgZ2xvYmFscywgbG9jYWxzLCBmaWxlLCBzZWxmLmRlYnVnZ2luZywgc2VsZi5ydW5fYXNfbWFpbiwgc2VsZi5wcm9maWxpbmcpCisJCWlmIGN3ZDoKKwkJCW9zLmNoZGlyKGN3ZCkKKwkKKwlkZWYgZ2V0ZW52aXJvbm1lbnQoc2VsZik6CisJCWlmIHNlbGYucGF0aDoKKwkJCWZpbGUgPSBzZWxmLnBhdGgKKwkJCW1vZG5hbWUgPSBfZmlsZW5hbWVfYXNfbW9kbmFtZShzZWxmLnRpdGxlKQorCQkJaWYgc3lzLm1vZHVsZXMuaGFzX2tleShtb2RuYW1lKToKKwkJCQlnbG9iYWxzID0gc3lzLm1vZHVsZXNbbW9kbmFtZV0uX19kaWN0X18KKwkJCQlzZWxmLmdsb2JhbHMgPSB7fQorCQkJZWxzZToKKwkJCQlnbG9iYWxzID0gc2VsZi5nbG9iYWxzCisJCWVsc2U6CisJCQlmaWxlID0gJzwlcz4nICUgc2VsZi50aXRsZQorCQkJZ2xvYmFscyA9IHNlbGYuZ2xvYmFscworCQlyZXR1cm4gZ2xvYmFscywgZmlsZQorCQorCWRlZiB3cml0ZShzZWxmLCBzdHVmZik6CisJCSIiImZvciB1c2UgYXMgc3Rkb3V0IiIiCisJCXNlbGYuX2J1ZiA9IHNlbGYuX2J1ZiArIHN0dWZmCisJCWlmICdcbicgaW4gc2VsZi5fYnVmOgorCQkJc2VsZi5mbHVzaCgpCisJCisJZGVmIGZsdXNoKHNlbGYpOgorCQlzdHVmZiA9IHN0cmluZy5zcGxpdChzZWxmLl9idWYsICdcbicpCisJCXN0dWZmID0gc3RyaW5nLmpvaW4oc3R1ZmYsICdccicpCisJCWVuZCA9IHNlbGYuZWRpdGdyb3VwLmVkaXRvci50ZWQuV0VHZXRUZXh0TGVuZ3RoKCkKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnRlZC5XRVNldFNlbGVjdGlvbihlbmQsIGVuZCkKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnRlZC5XRUluc2VydChzdHVmZiwgTm9uZSwgTm9uZSkKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLnVwZGF0ZXNjcm9sbGJhcnMoKQorCQlzZWxmLl9idWYgPSAiIgorCQkjID8gb3B0aW9uYWw6CisJCSNzZWxmLndpZC5TZWxlY3RXaW5kb3coKQorCQorCWRlZiBnZXRjbGFzc2xpc3Qoc2VsZik6CisJCWZyb20gc3RyaW5nIGltcG9ydCBmaW5kLCBzdHJpcAorCQllZGl0b3IgPSBzZWxmLmVkaXRncm91cC5lZGl0b3IKKwkJdGV4dCA9IGVkaXRvci5nZXQoKQorCQlsaXN0ID0gW10KKwkJYXBwZW5kID0gbGlzdC5hcHBlbmQKKwkJZnVuY3RhZyA9ICJmdW5jIgorCQljbGFzc3RhZyA9ICJjbGFzcyIKKwkJbWV0aG9kdGFnID0gIm1ldGhvZCIKKwkJcG9zID0gLTEKKwkJaWYgdGV4dFs6NF0gPT0gJ2RlZiAnOgorCQkJYXBwZW5kKChwb3MgKyA0LCBmdW5jdGFnKSkKKwkJCXBvcyA9IDQKKwkJd2hpbGUgMToKKwkJCXBvcyA9IGZpbmQodGV4dCwgJ1xyZGVmICcsIHBvcyArIDEpCisJCQlpZiBwb3MgPCAwOgorCQkJCWJyZWFrCisJCQlhcHBlbmQoKHBvcyArIDUsIGZ1bmN0YWcpKQorCQlwb3MgPSAtMQorCQlpZiB0ZXh0Wzo2XSA9PSAnY2xhc3MgJzoKKwkJCWFwcGVuZCgocG9zICsgNiwgY2xhc3N0YWcpKQorCQkJcG9zID0gNgorCQl3aGlsZSAxOgorCQkJcG9zID0gZmluZCh0ZXh0LCAnXHJjbGFzcyAnLCBwb3MgKyAxKQorCQkJaWYgcG9zIDwgMDoKKwkJCQlicmVhaworCQkJYXBwZW5kKChwb3MgKyA3LCBjbGFzc3RhZykpCisJCXBvcyA9IDAKKwkJd2hpbGUgMToKKwkJCXBvcyA9IGZpbmQodGV4dCwgJ1xyXHRkZWYgJywgcG9zICsgMSkKKwkJCWlmIHBvcyA8IDA6CisJCQkJYnJlYWsKKwkJCWFwcGVuZCgocG9zICsgNiwgbWV0aG9kdGFnKSkKKwkJbGlzdC5zb3J0KCkKKwkJY2xhc3NsaXN0ID0gW10KKwkJbWV0aG9kbGlzdGFwcGVuZCA9IE5vbmUKKwkJb2Zmc2V0VG9MaW5lID0gZWRpdG9yLnRlZC5XRU9mZnNldFRvTGluZQorCQlnZXRMaW5lUmFuZ2UgPSBlZGl0b3IudGVkLldFR2V0TGluZVJhbmdlCisJCWFwcGVuZCA9IGNsYXNzbGlzdC5hcHBlbmQKKwkJaWRlbnRpZmllUkVfbWF0Y2ggPSBfaWRlbnRpZmllUkUubWF0Y2gKKwkJZm9yIHBvcywgdGFnIGluIGxpc3Q6CisJCQlsaW5lbm8gPSBvZmZzZXRUb0xpbmUocG9zKQorCQkJbGluZVN0YXJ0LCBsaW5lRW5kID0gZ2V0TGluZVJhbmdlKGxpbmVubykKKwkJCWxpbmUgPSBzdHJpcCh0ZXh0W3BvczpsaW5lRW5kXSkKKwkJCWxpbmUgPSBsaW5lWzppZGVudGlmaWVSRV9tYXRjaChsaW5lKV0KKwkJCWlmIHRhZyBpcyBmdW5jdGFnOgorCQkJCWFwcGVuZCgoImRlZiAiICsgbGluZSwgbGluZW5vICsgMSkpCisJCQkJbWV0aG9kbGlzdGFwcGVuZCA9IE5vbmUKKwkJCWVsaWYgdGFnIGlzIGNsYXNzdGFnOgorCQkJCWFwcGVuZChbImNsYXNzICIgKyBsaW5lXSkKKwkJCQltZXRob2RsaXN0YXBwZW5kID0gY2xhc3NsaXN0Wy0xXS5hcHBlbmQKKwkJCWVsaWYgbWV0aG9kbGlzdGFwcGVuZCBhbmQgdGFnIGlzIG1ldGhvZHRhZzoKKwkJCQltZXRob2RsaXN0YXBwZW5kKCgiZGVmICIgKyBsaW5lLCBsaW5lbm8gKyAxKSkKKwkJcmV0dXJuIGNsYXNzbGlzdAorCQorCWRlZiBwb3BzZWxlY3RsaW5lKHNlbGYsIGxpbmVubyk6CisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5zZWxlY3RsaW5lKGxpbmVubyAtIDEpCisJCisJZGVmIHNlbGVjdGxpbmUoc2VsZiwgbGluZW5vLCBjaGFyb2Zmc2V0ID0gMCk6CisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5zZWxlY3RsaW5lKGxpbmVubyAtIDEsIGNoYXJvZmZzZXQpCisKKworY2xhc3MgUmVwb3J0ZXIoRWRpdG9yKToKKwkKKwlkZWYgY2xvc2Uoc2VsZik6CisJCXNlbGYuZ2xvYmFscyA9IE5vbmUKKwkJVy5XaW5kb3cuY2xvc2Uoc2VsZikKKwkKKwlkZWYgZG9tZW51X3J1bihzZWxmLCAqYXJncyk6CisJCXNlbGYucnVuKCkKKwkKKwlkZWYgZG9tZW51X3J1bnNlbGVjdGlvbihzZWxmLCAqYXJncyk6CisJCXNlbGYucnVuc2VsZWN0aW9uKCkKKwkKKwlkZWYgc2V0dXB3aWRnZXRzKHNlbGYsIHRleHQpOgorCQl0b3BiYXJoZWlnaHQgPSAtMQorCQlwb3BmaWVsZHdpZHRoID0gODAKKwkJc2VsZi5sYXN0bGluZW5vID0gTm9uZQorCQkKKwkJIyBtYWtlIGFuIGVkaXRvcgorCQlzZWxmLmVkaXRncm91cCA9IFcuR3JvdXAoKDAsIHRvcGJhcmhlaWdodCArIDEsIDAsIDApKQorCQlzZWxmLmVkaXRncm91cC5lZGl0b3IgPSBXLlB5RWRpdG9yKCgwLCAwLCAtMTUsLTE1KSwgdGV4dCkKKwkJCisJCSMgbWFrZSB0aGUgd2lkZ2V0cworCQlzZWxmLmVkaXRncm91cC5fYmFyeCA9IFcuU2Nyb2xsYmFyKChwb3BmaWVsZHdpZHRoLTIsIC0xNSwgLTE0LCAxNiksIHNlbGYuZWRpdGdyb3VwLmVkaXRvci5oc2Nyb2xsLCBtYXggPSAzMjc2NykKKwkJc2VsZi5lZGl0Z3JvdXAuX2JhcnkgPSBXLlNjcm9sbGJhcigoLTE1LCAtMSwgMTYsIC0xNCksIHNlbGYuZWRpdGdyb3VwLmVkaXRvci52c2Nyb2xsLCBtYXggPSAzMjc2NykKKwkJc2VsZi5obGluZSA9IFcuSG9yaXpvbnRhbExpbmUoKDAsIC0xNSwgMCwgMCkpCisJCQorCQkjIGJpbmQgc29tZSBrZXlzCisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5iaW5kKCJjbWRyIiwgc2VsZi5ydW4pCisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5iaW5kKCJlbnRlciIsIHNlbGYucnVuc2VsZWN0aW9uKQorCQkKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmJpbmQoImNtZGUiLCBzZWFyY2hlbmdpbmUuc2V0ZmluZHN0cmluZykKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmJpbmQoImNtZGYiLCBzZWFyY2hlbmdpbmUuc2hvdykKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmJpbmQoImNtZGciLCBzZWFyY2hlbmdpbmUuZmluZG5leHQpCisJCXNlbGYuZWRpdGdyb3VwLmVkaXRvci5iaW5kKCJjbWRzaGlmdHIiLCBzZWFyY2hlbmdpbmUucmVwbGFjZSkKKwkJc2VsZi5lZGl0Z3JvdXAuZWRpdG9yLmJpbmQoImNtZHQiLCBzZWFyY2hlbmdpbmUucmVwbGFjZWZpbmQpCisKKworZGVmIF9lc2NhcGUod2hlcmUsIHdoYXQpIDogCisJcmV0dXJuIHN0cmluZy5qb2luKHN0cmluZy5zcGxpdCh3aGVyZSwgd2hhdCksICdcXCcgKyB3aGF0KQorCitkZWYgX21ha2V3aG9sZXdvcmRwYXR0ZXJuKHdvcmQpOgorCSMgZmlyc3QsIGVzY2FwZSBzcGVjaWFsIHJlZ2V4IGNoYXJzCisJZm9yIGVzYyBpbiAiXFxbXS4qXiskPyI6CisJCXdvcmQgPSBfZXNjYXBlKHdvcmQsIGVzYykKKwlpbXBvcnQgcmVnZXgKKwlub3R3b3JkY2hhcnNwYXQgPSAnW14nICsgX3dvcmRjaGFycyArICddJworCXBhdHRlcm4gPSAnXCgnICsgd29yZCArICdcKScKKwlpZiB3b3JkWzBdIGluIF93b3JkY2hhcnM6CisJCXBhdHRlcm4gPSBub3R3b3JkY2hhcnNwYXQgKyBwYXR0ZXJuCisJaWYgd29yZFstMV0gaW4gX3dvcmRjaGFyczoKKwkJcGF0dGVybiA9IHBhdHRlcm4gKyBub3R3b3JkY2hhcnNwYXQKKwlyZXR1cm4gcmVnZXguY29tcGlsZShwYXR0ZXJuKQorCitjbGFzcyBTZWFyY2hFbmdpbmU6CisJCisJZGVmIF9faW5pdF9fKHNlbGYpOgorCQlzZWxmLnZpc2libGUgPSAwCisJCXNlbGYudyA9IE5vbmUKKwkJc2VsZi5wYXJtcyA9IHsgICJmaW5kIjogIiIsCisJCQkJCSJyZXBsYWNlIjogIiIsCisJCQkJCSJ3cmFwIjogMSwKKwkJCQkJImNhc2VzZW5zIjogMSwKKwkJCQkJIndob2xld29yZCI6IDEKKwkJCQl9CisJCWltcG9ydCBNYWNQcmVmcworCQlwcmVmcyA9IE1hY1ByZWZzLkdldFByZWZzKFcuZ2V0YXBwbGljYXRpb24oKS5wcmVmZmlsZXBhdGgpCisJCWlmIHByZWZzLnNlYXJjaGVuZ2luZToKKwkJCXNlbGYucGFybXNbImNhc2VzZW5zIl0gPSBwcmVmcy5zZWFyY2hlbmdpbmUuY2FzZXNlbnMKKwkJCXNlbGYucGFybXNbIndyYXAiXSA9IHByZWZzLnNlYXJjaGVuZ2luZS53cmFwCisJCQlzZWxmLnBhcm1zWyJ3aG9sZXdvcmQiXSA9IHByZWZzLnNlYXJjaGVuZ2luZS53aG9sZXdvcmQKKwkKKwlkZWYgc2hvdyhzZWxmKToKKwkJc2VsZi52aXNpYmxlID0gMQorCQlpZiBzZWxmLnc6CisJCQlzZWxmLncud2lkLlNob3dXaW5kb3coKQorCQkJc2VsZi53LndpZC5TZWxlY3RXaW5kb3coKQorCQkJc2VsZi53LmZpbmQuZWRpdC5zZWxlY3QoMSkKKwkJCXNlbGYudy5maW5kLmVkaXQuc2VsZWN0YWxsKCkKKwkJCXJldHVybgorCQlzZWxmLncgPSBXLkRpYWxvZygoNDIwLCAxNTApLCAiRmluZCIpCisJCQorCQlzZWxmLncuZmluZCA9IFRpdGxlZEVkaXRUZXh0KCgxMCwgNCwgMzAwLCAzNiksICJTZWFyY2ggZm9yOiIpCisJCXNlbGYudy5yZXBsYWNlID0gVGl0bGVkRWRpdFRleHQoKDEwLCAxMDAsIDMwMCwgMzYpLCAiUmVwbGFjZSB3aXRoOiIpCisJCQorCQlzZWxmLncuYm94ZXMgPSBXLkdyb3VwKCgxMCwgNTAsIDMwMCwgNDApKQorCQlzZWxmLncuYm94ZXMuY2FzZXNlbnMgPSBXLkNoZWNrQm94KCgwLCAwLCAxMDAsIDE2KSwgIkNhc2Ugc2Vuc2l0aXZlIikKKwkJc2VsZi53LmJveGVzLndob2xld29yZCA9IFcuQ2hlY2tCb3goKDAsIDIwLCAxMDAsIDE2KSwgIldob2xlIHdvcmQiKQorCQlzZWxmLncuYm94ZXMud3JhcCA9IFcuQ2hlY2tCb3goKDExMCwgMCwgMTAwLCAxNiksICJXcmFwIGFyb3VuZCIpCisJCQorCQlzZWxmLmJ1dHRvbnMgPSBbCSgiRmluZCIsCQkiY21kZiIsCSBzZWxmLmZpbmQpLCAKKwkJCQkJKCJSZXBsYWNlIiwJICAgICAiY21kciIsCSBzZWxmLnJlcGxhY2UpLCAKKwkJCQkJKCJSZXBsYWNlIGFsbCIsCSBOb25lLCAgIHNlbGYucmVwbGFjZWFsbCksIAorCQkJCQkoIkRvbrl0IGZpbmQiLCAgImNtZGQiLAkgc2VsZi5kb250KSwgCisJCQkJCSgiQ2FuY2VsIiwJICAgICAgImNtZC4iLAkgc2VsZi5jYW5jZWwpCisJCQkJXQorCQlmb3IgaSBpbiByYW5nZShsZW4oc2VsZi5idXR0b25zKSk6CisJCQlib3VuZHMgPSAtOTAsIDIyICsgaSAqIDI0LCA4MCwgMTYKKwkJCXRpdGxlLCBzaG9ydGN1dCwgY2FsbGJhY2sgPSBzZWxmLmJ1dHRvbnNbaV0KKwkJCXNlbGYud1t0aXRsZV0gPSBXLkJ1dHRvbihib3VuZHMsIHRpdGxlLCBjYWxsYmFjaykKKwkJCWlmIHNob3J0Y3V0OgorCQkJCXNlbGYudy5iaW5kKHNob3J0Y3V0LCBzZWxmLndbdGl0bGVdLnB1c2gpCisJCXNlbGYudy5zZXRkZWZhdWx0YnV0dG9uKHNlbGYud1siRG9uuXQgZmluZCJdKQorCQlzZWxmLncuZmluZC5lZGl0LmJpbmQoIjxrZXk+Iiwgc2VsZi5rZXkpCisJCXNlbGYudy5iaW5kKCI8YWN0aXZhdGU+Iiwgc2VsZi5hY3RpdmF0ZSkKKwkJc2VsZi53Lm9wZW4oKQorCQlzZWxmLnNldHBhcm1zKCkKKwkJc2VsZi53LmZpbmQuZWRpdC5zZWxlY3QoMSkKKwkJc2VsZi53LmZpbmQuZWRpdC5zZWxlY3RhbGwoKQorCQlzZWxmLmNoZWNrYnV0dG9ucygpCisJCisJZGVmIGtleShzZWxmLCBjaGFyLCBtb2RpZmllcnMpOgorCQlzZWxmLncuZmluZC5lZGl0LmtleShjaGFyLCBtb2RpZmllcnMpCisJCXNlbGYuY2hlY2tidXR0b25zKCkKKwkJcmV0dXJuIDEKKwkKKwlkZWYgYWN0aXZhdGUoc2VsZiwgb25vZmYpOgorCQlpZiBvbm9mZjoKKwkJCXNlbGYuY2hlY2tidXR0b25zKCkKKwkKKwlkZWYgY2hlY2tidXR0b25zKHNlbGYpOgorCQllZGl0b3IgPSBmaW5kZWRpdG9yKHNlbGYpCisJCWlmIGVkaXRvcjoKKwkJCWlmIHNlbGYudy5maW5kLmdldCgpOgorCQkJCWZvciB0aXRsZSwgY21kLCBjYWxsIGluIHNlbGYuYnV0dG9uc1s6LTJdOgorCQkJCQlzZWxmLndbdGl0bGVdLmVuYWJsZSgxKQorCQkJCXNlbGYudy5zZXRkZWZhdWx0YnV0dG9uKHNlbGYud1siRmluZCJdKQorCQkJZWxzZToKKwkJCQlmb3IgdGl0bGUsIGNtZCwgY2FsbCBpbiBzZWxmLmJ1dHRvbnNbOi0yXToKKwkJCQkJc2VsZi53W3RpdGxlXS5lbmFibGUoMCkKKwkJCQlzZWxmLncuc2V0ZGVmYXVsdGJ1dHRvbihzZWxmLndbIkRvbrl0IGZpbmQiXSkKKwkJZWxzZToKKwkJCWZvciB0aXRsZSwgY21kLCBjYWxsIGluIHNlbGYuYnV0dG9uc1s6LTJdOgorCQkJCXNlbGYud1t0aXRsZV0uZW5hYmxlKDApCisJCQlzZWxmLncuc2V0ZGVmYXVsdGJ1dHRvbihzZWxmLndbIkRvbrl0IGZpbmQiXSkKKwkKKwlkZWYgZmluZChzZWxmKToKKwkJc2VsZi5nZXRwYXJtc2Zyb213aW5kb3coKQorCQlpZiBzZWxmLmZpbmRuZXh0KCk6CisJCQlzZWxmLmhpZGUoKQorCQorCWRlZiByZXBsYWNlKHNlbGYpOgorCQllZGl0b3IgPSBmaW5kZWRpdG9yKHNlbGYpCisJCWlmIG5vdCBlZGl0b3I6CisJCQlyZXR1cm4KKwkJaWYgc2VsZi52aXNpYmxlOgorCQkJc2VsZi5nZXRwYXJtc2Zyb213aW5kb3coKQorCQl0ZXh0ID0gZWRpdG9yLmdldHNlbGVjdGVkdGV4dCgpCisJCWZpbmQgPSBzZWxmLnBhcm1zWyJmaW5kIl0KKwkJaWYgbm90IHNlbGYucGFybXNbImNhc2VzZW5zIl06CisJCQlmaW5kID0gc3RyaW5nLmxvd2VyKGZpbmQpCisJCQl0ZXh0ID0gc3RyaW5nLmxvd2VyKHRleHQpCisJCWlmIHRleHQgPT0gZmluZDoKKwkJCXNlbGYuaGlkZSgpCisJCQllZGl0b3IuaW5zZXJ0KHNlbGYucGFybXNbInJlcGxhY2UiXSkKKwkKKwlkZWYgcmVwbGFjZWFsbChzZWxmKToKKwkJZWRpdG9yID0gZmluZGVkaXRvcihzZWxmKQorCQlpZiBub3QgZWRpdG9yOgorCQkJcmV0dXJuCisJCWlmIHNlbGYudmlzaWJsZToKKwkJCXNlbGYuZ2V0cGFybXNmcm9td2luZG93KCkKKwkJVy5TZXRDdXJzb3IoIndhdGNoIikKKwkJZmluZCA9IHNlbGYucGFybXNbImZpbmQiXQorCQlpZiBub3QgZmluZDoKKwkJCXJldHVybgorCQlmaW5kbGVuID0gbGVuKGZpbmQpCisJCXJlcGxhY2UgPSBzZWxmLnBhcm1zWyJyZXBsYWNlIl0KKwkJcmVwbGFjZWxlbiA9IGxlbihyZXBsYWNlKQorCQlUZXh0ID0gZWRpdG9yLmdldCgpCisJCWlmIG5vdCBzZWxmLnBhcm1zWyJjYXNlc2VucyJdOgorCQkJZmluZCA9IHN0cmluZy5sb3dlcihmaW5kKQorCQkJdGV4dCA9IHN0cmluZy5sb3dlcihUZXh0KQorCQllbHNlOgorCQkJdGV4dCA9IFRleHQKKwkJbmV3dGV4dCA9ICIiCisJCXBvcyA9IDAKKwkJY291bnRlciA9IDAKKwkJd2hpbGUgMToKKwkJCWlmIHNlbGYucGFybXNbIndob2xld29yZCJdOgorCQkJCXdob2xld29yZFJFID0gX21ha2V3aG9sZXdvcmRwYXR0ZXJuKGZpbmQpCisJCQkJd2hvbGV3b3JkUkUuc2VhcmNoKHRleHQsIHBvcykKKwkJCQlpZiB3aG9sZXdvcmRSRS5yZWdzOgorCQkJCQlwb3MgPSB3aG9sZXdvcmRSRS5yZWdzWzFdWzBdCisJCQkJZWxzZToKKwkJCQkJcG9zID0gLTEKKwkJCWVsc2U6CisJCQkJcG9zID0gc3RyaW5nLmZpbmQodGV4dCwgZmluZCwgcG9zKQorCQkJaWYgcG9zIDwgMDoKKwkJCQlicmVhaworCQkJY291bnRlciA9IGNvdW50ZXIgKyAxCisJCQl0ZXh0ID0gdGV4dFs6cG9zXSArIHJlcGxhY2UgKyB0ZXh0W3BvcyArIGZpbmRsZW46XQorCQkJVGV4dCA9IFRleHRbOnBvc10gKyByZXBsYWNlICsgVGV4dFtwb3MgKyBmaW5kbGVuOl0KKwkJCXBvcyA9IHBvcyArIHJlcGxhY2VsZW4KKwkJVy5TZXRDdXJzb3IoImFycm93IikKKwkJaWYgY291bnRlcjoKKwkJCXNlbGYuaGlkZSgpCisJCQlpbXBvcnQgRWFzeURpYWxvZ3MKKwkJCWltcG9ydCBSZXMKKwkJCWVkaXRvci5jaGFuZ2VkID0gMQorCQkJZWRpdG9yLnNlbGNoYW5nZWQgPSAxCisJCQllZGl0b3IudGVkLldFVXNlVGV4dChSZXMuUmVzb3VyY2UoVGV4dCkpCisJCQllZGl0b3IudGVkLldFQ2FsVGV4dCgpCisJCQllZGl0b3IuU2V0UG9ydCgpCisJCQlXaW4uSW52YWxSZWN0KGVkaXRvci5fYm91bmRzKQorCQkJI2VkaXRvci50ZWQuV0VVcGRhdGUoc2VsZi53LndpZC5HZXRXaW5kb3dQb3J0KCkudmlzUmduKQorCQkJRWFzeURpYWxvZ3MuTWVzc2FnZSgiUmVwbGFjZWQgJWQgb2NjdXJyZW5jZXMiICUgY291bnRlcikKKwkKKwlkZWYgZG9udChzZWxmKToKKwkJc2VsZi5nZXRwYXJtc2Zyb213aW5kb3coKQorCQlzZWxmLmhpZGUoKQorCQorCWRlZiByZXBsYWNlZmluZChzZWxmKToKKwkJc2VsZi5yZXBsYWNlKCkKKwkJc2VsZi5maW5kbmV4dCgpCisJCisJZGVmIHNldGZpbmRzdHJpbmcoc2VsZik6CisJCWVkaXRvciA9IGZpbmRlZGl0b3Ioc2VsZikKKwkJaWYgbm90IGVkaXRvcjoKKwkJCXJldHVybgorCQlmaW5kID0gZWRpdG9yLmdldHNlbGVjdGVkdGV4dCgpCisJCWlmIG5vdCBmaW5kOgorCQkJcmV0dXJuCisJCXNlbGYucGFybXNbImZpbmQiXSA9IGZpbmQKKwkJaWYgc2VsZi53OgorCQkJc2VsZi53LmZpbmQuZWRpdC5zZXQoc2VsZi5wYXJtc1siZmluZCJdKQorCQkJc2VsZi53LmZpbmQuZWRpdC5zZWxlY3RhbGwoKQorCQorCWRlZiBmaW5kbmV4dChzZWxmKToKKwkJZWRpdG9yID0gZmluZGVkaXRvcihzZWxmKQorCQlpZiBub3QgZWRpdG9yOgorCQkJcmV0dXJuCisJCWZpbmQgPSBzZWxmLnBhcm1zWyJmaW5kIl0KKwkJaWYgbm90IGZpbmQ6CisJCQlyZXR1cm4KKwkJdGV4dCA9IGVkaXRvci5nZXQoKQorCQlpZiBub3Qgc2VsZi5wYXJtc1siY2FzZXNlbnMiXToKKwkJCWZpbmQgPSBzdHJpbmcubG93ZXIoZmluZCkKKwkJCXRleHQgPSBzdHJpbmcubG93ZXIodGV4dCkKKwkJc2Vsc3RhcnQsIHNlbGVuZCA9IGVkaXRvci5nZXRzZWxlY3Rpb24oKQorCQlzZWxzdGFydCwgc2VsZW5kID0gbWluKHNlbHN0YXJ0LCBzZWxlbmQpLCBtYXgoc2Vsc3RhcnQsIHNlbGVuZCkKKwkJaWYgc2VsZi5wYXJtc1sid2hvbGV3b3JkIl06CisJCQl3aG9sZXdvcmRSRSA9IF9tYWtld2hvbGV3b3JkcGF0dGVybihmaW5kKQorCQkJd2hvbGV3b3JkUkUuc2VhcmNoKHRleHQsIHNlbGVuZCkKKwkJCWlmIHdob2xld29yZFJFLnJlZ3M6CisJCQkJcG9zID0gd2hvbGV3b3JkUkUucmVnc1sxXVswXQorCQkJZWxzZToKKwkJCQlwb3MgPSAtMQorCQllbHNlOgorCQkJcG9zID0gc3RyaW5nLmZpbmQodGV4dCwgZmluZCwgc2VsZW5kKQorCQlpZiBwb3MgPj0gMDoKKwkJCWVkaXRvci5zZXRzZWxlY3Rpb24ocG9zLCBwb3MgKyBsZW4oZmluZCkpCisJCQlyZXR1cm4gMQorCQllbGlmIHNlbGYucGFybXNbIndyYXAiXToKKwkJCWlmIHNlbGYucGFybXNbIndob2xld29yZCJdOgorCQkJCXdob2xld29yZFJFLnNlYXJjaCh0ZXh0LCAwKQorCQkJCWlmIHdob2xld29yZFJFLnJlZ3M6CisJCQkJCXBvcyA9IHdob2xld29yZFJFLnJlZ3NbMV1bMF0KKwkJCQllbHNlOgorCQkJCQlwb3MgPSAtMQorCQkJZWxzZToKKwkJCQlwb3MgPSBzdHJpbmcuZmluZCh0ZXh0LCBmaW5kKQorCQkJaWYgc2Vsc3RhcnQgPiBwb3MgPj0gMDoKKwkJCQllZGl0b3Iuc2V0c2VsZWN0aW9uKHBvcywgcG9zICsgbGVuKGZpbmQpKQorCQkJCXJldHVybiAxCisJCisJZGVmIHNldHBhcm1zKHNlbGYpOgorCQlmb3Iga2V5LCB2YWx1ZSBpbiBzZWxmLnBhcm1zLml0ZW1zKCk6CisJCQl0cnk6CisJCQkJc2VsZi53W2tleV0uc2V0KHZhbHVlKQorCQkJZXhjZXB0IEtleUVycm9yOgorCQkJCXNlbGYudy5ib3hlc1trZXldLnNldCh2YWx1ZSkKKwkKKwlkZWYgZ2V0cGFybXNmcm9td2luZG93KHNlbGYpOgorCQlpZiBub3Qgc2VsZi53OgorCQkJcmV0dXJuCisJCWZvciBrZXksIHZhbHVlIGluIHNlbGYucGFybXMuaXRlbXMoKToKKwkJCXRyeToKKwkJCQl2YWx1ZSA9IHNlbGYud1trZXldLmdldCgpCisJCQlleGNlcHQgS2V5RXJyb3I6CisJCQkJdmFsdWUgPSBzZWxmLncuYm94ZXNba2V5XS5nZXQoKQorCQkJc2VsZi5wYXJtc1trZXldID0gdmFsdWUKKwkKKwlkZWYgY2FuY2VsKHNlbGYpOgorCQlzZWxmLmhpZGUoKQorCQlzZWxmLnNldHBhcm1zKCkKKwkKKwlkZWYgaGlkZShzZWxmKToKKwkJaWYgc2VsZi53OgorCQkJc2VsZi53LndpZC5IaWRlV2luZG93KCkKKwkJCXNlbGYudmlzaWJsZSA9IDAKKwkKKwlkZWYgd3JpdGVwcmVmcyhzZWxmKToKKwkJaW1wb3J0IE1hY1ByZWZzCisJCXNlbGYuZ2V0cGFybXNmcm9td2luZG93KCkKKwkJcHJlZnMgPSBNYWNQcmVmcy5HZXRQcmVmcyhXLmdldGFwcGxpY2F0aW9uKCkucHJlZmZpbGVwYXRoKQorCQlwcmVmcy5zZWFyY2hlbmdpbmUuY2FzZXNlbnMgPSBzZWxmLnBhcm1zWyJjYXNlc2VucyJdCisJCXByZWZzLnNlYXJjaGVuZ2luZS53cmFwID0gc2VsZi5wYXJtc1sid3JhcCJdCisJCXByZWZzLnNlYXJjaGVuZ2luZS53aG9sZXdvcmQgPSBzZWxmLnBhcm1zWyJ3aG9sZXdvcmQiXQorCQlwcmVmcy5zYXZlKCkKKwkKKworY2xhc3MgVGl0bGVkRWRpdFRleHQoVy5Hcm91cCk6CisJCisJZGVmIF9faW5pdF9fKHNlbGYsIHBvc3NpemUsIHRpdGxlLCB0ZXh0ID0gIiIpOgorCQlXLkdyb3VwLl9faW5pdF9fKHNlbGYsIHBvc3NpemUpCisJCXNlbGYudGl0bGUgPSBXLlRleHRCb3goKDAsIDAsIDAsIDE2KSwgdGl0bGUpCisJCXNlbGYuZWRpdCA9IFcuRWRpdFRleHQoKDAsIDE2LCAwLCAwKSwgdGV4dCkKKwkKKwlkZWYgc2V0KHNlbGYsIHZhbHVlKToKKwkJc2VsZi5lZGl0LnNldCh2YWx1ZSkKKwkKKwlkZWYgZ2V0KHNlbGYpOgorCQlyZXR1cm4gc2VsZi5lZGl0LmdldCgpCisKKworY2xhc3MgQ2xhc3NGaW5kZXIoVy5Qb3B1cFdpZGdldCk6CisJCisJZGVmIGNsaWNrKHNlbGYsIHBvaW50LCBtb2RpZmllcnMpOgorCQlXLlNldEN1cnNvcigid2F0Y2giKQorCQlzZWxmLnNldChzZWxmLl9wYXJlbnR3aW5kb3cuZ2V0Y2xhc3NsaXN0KCkpCisJCVcuUG9wdXBXaWRnZXQuY2xpY2soc2VsZiwgcG9pbnQsIG1vZGlmaWVycykKKworCitkZWYgZ2V0bWluaW5kZW50KGxpbmVzKToKKwlpbmRlbnQgPSAtMQorCWZvciBsaW5lIGluIGxpbmVzOgorCQlzdHJpcHBlZCA9IHN0cmluZy5zdHJpcChsaW5lKQorCQlpZiBub3Qgc3RyaXBwZWQgb3Igc3RyaXBwZWRbMF0gPT0gJyMnOgorCQkJY29udGludWUKKwkJaWYgaW5kZW50IDwgMCBvciBsaW5lWzppbmRlbnRdIDw+IGluZGVudCAqICdcdCc6CisJCQlpbmRlbnQgPSAwCisJCQlmb3IgYyBpbiBsaW5lOgorCQkJCWlmIGMgPD4gJ1x0JzoKKwkJCQkJYnJlYWsKKwkJCQlpbmRlbnQgPSBpbmRlbnQgKyAxCisJcmV0dXJuIGluZGVudAorCisKK2RlZiBnZXRvcHRpb25rZXkoKToKKwlyZXR1cm4gbm90IG5vdCBvcmQoRXZ0LkdldEtleXMoKVs3XSkgJiAweDA0CisKKworZGVmIGV4ZWNzdHJpbmcocHl0ZXh0LCBnbG9iYWxzLCBsb2NhbHMsIGZpbGVuYW1lID0gIjxzdHJpbmc+IiwgZGVidWdnaW5nID0gMCwgCisJCQlydW5fYXNfbWFpbiA9IDAsIHByb2ZpbGluZyA9IDApOgorCWlmIGRlYnVnZ2luZzoKKwkJaW1wb3J0IFB5RGVidWdnZXIsIGJkYgorCQlCZGJRdWl0ID0gYmRiLkJkYlF1aXQKKwllbHNlOgorCQlCZGJRdWl0ID0gJ0JkYlF1aXREdW1teUV4Y2VwdGlvbicKKwlweXRleHQgPSBzdHJpbmcuc3BsaXQocHl0ZXh0LCAnXHInKQorCXB5dGV4dCA9IHN0cmluZy5qb2luKHB5dGV4dCwgJ1xuJykgKyAnXG4nCisJVy5TZXRDdXJzb3IoIndhdGNoIikKKwltb2RuYW1lID0gb3MucGF0aC5iYXNlbmFtZShmaWxlbmFtZSkKKwlpZiBtb2RuYW1lWy0zOl0gPT0gJy5weSc6CisJCW1vZG5hbWUgPSBtb2RuYW1lWzotM10KKwlpZiBydW5fYXNfbWFpbjoKKwkJZ2xvYmFsc1snX19uYW1lX18nXSA9ICdfX21haW5fXycKKwllbHNlOgorCQlnbG9iYWxzWydfX25hbWVfXyddID0gbW9kbmFtZQorCWdsb2JhbHNbJ19fZmlsZV9fJ10gPSBmaWxlbmFtZQorCXN5cy5hcmd2ID0gW2ZpbGVuYW1lXQorCXRyeToKKwkJY29kZSA9IGNvbXBpbGUocHl0ZXh0LCBmaWxlbmFtZSwgImV4ZWMiKQorCWV4Y2VwdDoKKwkJdHJhY2ViYWNrd2luZG93LnRyYWNlYmFjaygxLCBmaWxlbmFtZSkKKwkJcmV0dXJuCisJdHJ5OgorCQlpZiBkZWJ1Z2dpbmc6CisJCQlQeURlYnVnZ2VyLnN0YXJ0ZnJvbWhlcmUoKQorCQllbHNlOgorCQkJTWFjT1MuRW5hYmxlQXBwc3dpdGNoKDApCisJCXRyeToKKwkJCWlmIHByb2ZpbGluZzoKKwkJCQlpbXBvcnQgcHJvZmlsZSwgUHJvZmlsZUJyb3dzZXIKKwkJCQlwID0gcHJvZmlsZS5Qcm9maWxlKFByb2ZpbGVCcm93c2VyLnRpbWVyKQorCQkJCXAuc2V0X2NtZChmaWxlbmFtZSkKKwkJCQl0cnk6CisJCQkJCXAucnVuY3R4KGNvZGUsIGdsb2JhbHMsIGxvY2FscykKKwkJCQlmaW5hbGx5OgorCQkJCQlpbXBvcnQgcHN0YXRzCisJCQkJCQorCQkJCQlzdGF0cyA9IHBzdGF0cy5TdGF0cyhwKQorCQkJCQlQcm9maWxlQnJvd3Nlci5Qcm9maWxlQnJvd3NlcihzdGF0cykKKwkJCWVsc2U6CisJCQkJZXhlYyBjb2RlIGluIGdsb2JhbHMsIGxvY2FscworCQlmaW5hbGx5OgorCQkJTWFjT1MuRW5hYmxlQXBwc3dpdGNoKC0xKQorCWV4Y2VwdCBXLkFsZXJ0RXJyb3IsIGRldGFpbDoKKwkJcmFpc2UgVy5BbGVydEVycm9yLCBkZXRhaWwKKwlleGNlcHQgKEtleWJvYXJkSW50ZXJydXB0LCBCZGJRdWl0KToKKwkJcGFzcworCWV4Y2VwdDoKKwkJaWYgZGVidWdnaW5nOgorCQkJc3lzLnNldHRyYWNlKE5vbmUpCisJCQlQeURlYnVnZ2VyLnBvc3Rtb3J0ZW0oc3lzLmV4Y190eXBlLCBzeXMuZXhjX3ZhbHVlLCBzeXMuZXhjX3RyYWNlYmFjaykKKwkJCXJldHVybgorCQllbHNlOgorCQkJdHJhY2ViYWNrd2luZG93LnRyYWNlYmFjaygxLCBmaWxlbmFtZSkKKwlpZiBkZWJ1Z2dpbmc6CisJCXN5cy5zZXR0cmFjZShOb25lKQorCQlQeURlYnVnZ2VyLnN0b3AoKQorCisKK19pZGVudGlmaWVSRSA9IHJlZ2V4LmNvbXBpbGUoIltBLVphLXpfXVtBLVphLXpfMC05XSoiKQorCitkZWYgX2ZpbGVuYW1lX2FzX21vZG5hbWUoZm5hbWUpOgorCWlmIGZuYW1lWy0zOl0gPT0gJy5weSc6CisJCW1uYW1lID0gZm5hbWVbOi0zXQorCQlpZiBfaWRlbnRpZmllUkUubWF0Y2gobW5hbWUpID09IGxlbihtbmFtZSk6CisJCQlyZXR1cm4gbW5hbWUKKworZGVmIGZpbmRlZGl0b3IodG9wd2luZG93LCBmcm9tdG9wID0gMCk6CisJd2lkID0gV2luLkZyb250V2luZG93KCkKKwlpZiBub3QgZnJvbXRvcDoKKwkJaWYgdG9wd2luZG93LncgYW5kIHdpZCA9PSB0b3B3aW5kb3cudy53aWQ6CisJCQl3aWQgPSB0b3B3aW5kb3cudy53aWQuR2V0TmV4dFdpbmRvdygpCisJaWYgbm90IHdpZDoKKwkJcmV0dXJuCisJd2luZG93ID0gVy5nZXRhcHBsaWNhdGlvbigpLl93aW5kb3dzW3dpZF0KKwlpZiBub3QgVy5IYXNCYXNlQ2xhc3Mod2luZG93LCBFZGl0b3IpOgorCQlyZXR1cm4KKwlyZXR1cm4gd2luZG93LmVkaXRncm91cC5lZGl0b3IKKworCitzZWFyY2hlbmdpbmUgPSBTZWFyY2hFbmdpbmUoKQordHJhY2ViYWNrd2luZG93ID0gV3RyYWNlYmFjay5UcmFjZUJhY2soKQpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1B5Rm9udGlmeS5weSBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9QeUZvbnRpZnkucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNjUwMzYzNgotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9QeUZvbnRpZnkucHkKQEAgLTAsMCArMSwxNTMgQEAKKyIiIk1vZHVsZSB0byBhbmFseXplIFB5dGhvbiBzb3VyY2UgY29kZTsgZm9yIHN5bnRheCBjb2xvcmluZyB0b29scy4KKworSW50ZXJmYWNlOgorCXRhZ3MgPSBmb250aWZ5KHB5dGV4dCwgc2VhcmNoZnJvbSwgc2VhcmNodG8pCisKK1RoZSAncHl0ZXh0JyBhcmd1bWVudCBpcyBhIHN0cmluZyBjb250YWluaW5nIFB5dGhvbiBzb3VyY2UgY29kZS4KK1RoZSAob3B0aW9uYWwpIGFyZ3VtZW50cyAnc2VhcmNoZnJvbScgYW5kICdzZWFyY2h0bycgbWF5IGNvbnRhaW4gYSBzbGljZSBpbiBweXRleHQuIAorVGhlIHJldHVybmVkIHZhbHVlIGlzIGEgbGlzdHMgb2YgdHVwbGVzLCBmb3JtYXR0ZWQgbGlrZSB0aGlzOgorCVsoJ2tleXdvcmQnLCAwLCA2LCBOb25lKSwgKCdrZXl3b3JkJywgMTEsIDE3LCBOb25lKSwgKCdjb21tZW50JywgMjMsIDUzLCBOb25lKSwgZXRjLiBdCitUaGUgdHVwbGUgY29udGVudHMgYXJlIGFsd2F5cyBsaWtlIHRoaXM6CisJKHRhZywgc3RhcnRpbmRleCwgZW5kaW5kZXgsIHN1Ymxpc3QpCit0YWcgaXMgb25lIG9mICdrZXl3b3JkJywgJ3N0cmluZycsICdjb21tZW50JyBvciAnaWRlbnRpZmllcicKK3N1Ymxpc3QgaXMgbm90IHVzZWQsIGhlbmNlIGFsd2F5cyBOb25lLiAKKyIiIgorCisjIEJhc2VkIG9uIEZvbnRUZXh0LnB5IGJ5IE1pdGNoZWxsIFMuIENoYXBtYW4sCisjIHdoaWNoIHdhcyBtb2RpZmllZCBieSBaYWNoYXJ5IFJvYWRob3VzZSwKKyMgdGhlbiB1bi1UaydkIGJ5IEp1c3QgdmFuIFJvc3N1bS4KKyMgTWFueSB0aGFua3MgZm9yIHJlZ3VsYXIgZXhwcmVzc2lvbiBkZWJ1Z2dpbmcgJiBhdXRob3JpbmcgYXJlIGR1ZSB0bzoKKyMJVGltICh0aGUtaW5jcmVkaWItbHkgeSdycykgUGV0ZXJzIGFuZCBDcmlzdGlhbiBUaXNtZXIKKyMgU28sIHdobyBvd25zIHRoZSBjb3B5cmlnaHQ/IDstKSBIb3cgYWJvdXQgdGhpczoKKyMgQ29weXJpZ2h0IDE5OTYtMTk5NzogCisjCU1pdGNoZWxsIFMuIENoYXBtYW4sCisjCVphY2hhcnkgUm9hZGhvdXNlLAorIwlUaW0gUGV0ZXJzLAorIwlKdXN0IHZhbiBSb3NzdW0KKworX192ZXJzaW9uX18gPSAiMC4zLjEiCisKK2ltcG9ydCBzdHJpbmcsIHJlZ2V4CisKKyMgRmlyc3QgYSBsaXR0bGUgaGVscGVyLCBzaW5jZSBJIGRvbid0IGxpa2UgdG8gcmVwZWF0IHRoaW5ncy4gKFRpc21lciBzcGVha2luZykKK2ltcG9ydCBzdHJpbmcKK2RlZiByZXBsYWNlKHdoZXJlLCB3aGF0LCB3aXRoKToKKwlyZXR1cm4gc3RyaW5nLmpvaW4oc3RyaW5nLnNwbGl0KHdoZXJlLCB3aGF0KSwgd2l0aCkKKworIyBUaGlzIGxpc3Qgb2Yga2V5d29yZHMgaXMgdGFrZW4gZnJvbSByZWYvbm9kZTEzLmh0bWwgb2YgdGhlCisjIFB5dGhvbiAxLjMgSFRNTCBkb2N1bWVudGF0aW9uLiAoImFjY2VzcyIgaXMgaW50ZW50aW9uYWxseSBvbWl0dGVkLikKK2tleXdvcmRzTGlzdCA9IFsKKwkiZGVsIiwgImZyb20iLCAibGFtYmRhIiwgInJldHVybiIsCisJImFuZCIsICJlbGlmIiwgImdsb2JhbCIsICJub3QiLCAidHJ5IiwKKwkiYnJlYWsiLCAiZWxzZSIsICJpZiIsICJvciIsICJ3aGlsZSIsCisJImNsYXNzIiwgImV4Y2VwdCIsICJpbXBvcnQiLCAicGFzcyIsCisJImNvbnRpbnVlIiwgImZpbmFsbHkiLCAiaW4iLCAicHJpbnQiLAorCSJkZWYiLCAiZm9yIiwgImlzIiwgInJhaXNlIl0KKworIyBCdWlsZCB1cCBhIHJlZ3VsYXIgZXhwcmVzc2lvbiB3aGljaCB3aWxsIG1hdGNoIGFueXRoaW5nCisjIGludGVyZXN0aW5nLCBpbmNsdWRpbmcgbXVsdGktbGluZSB0cmlwbGUtcXVvdGVkIHN0cmluZ3MuCitjb21tZW50UGF0ID0gIiMuKiIKKworcGF0ID0gInFbXlxxXG5dKlwoXFxcXFtcMDAwLVwzNzddW15ccVxuXSpcKSpxIgorcXVvdGVQYXQgPSByZXBsYWNlKHBhdCwgInEiLCAiJyIpICsgIlx8IiArIHJlcGxhY2UocGF0LCAncScsICciJykKKworIyBXYXkgdG8gZ28sIFRpbSEKK3BhdCA9ICIiIgorCXFxcQorCVteXFxxXSoKKwlcKAorCQlcKAlcXFxcW1wwMDAtXDM3N10KKwkJXHwJcQorCQkJXCgJXFxcXFtcMDAwLVwzNzddCisJCQlcfAlbXlxccV0KKwkJCVx8CXEKKwkJCQlcKAlcXFxcW1wwMDAtXDM3N10KKwkJCQlcfAlbXlxccV0KKwkJCQlcKQorCQkJXCkKKwkJXCkKKwkJW15cXHFdKgorCVwpKgorCXFxcQorIiIiCitwYXQgPSBzdHJpbmcuam9pbihzdHJpbmcuc3BsaXQocGF0KSwgJycpCSMgZ2V0IHJpZCBvZiB3aGl0ZXNwYWNlCit0cmlwbGVRdW90ZVBhdCA9IHJlcGxhY2UocGF0LCAicSIsICInIikgKyAiXHwiICsgcmVwbGFjZShwYXQsICdxJywgJyInKQorCisjIEJ1aWxkIHVwIGEgcmVndWxhciBleHByZXNzaW9uIHdoaWNoIG1hdGNoZXMgYWxsIGFuZCBvbmx5CisjIFB5dGhvbiBrZXl3b3Jkcy4gVGhpcyB3aWxsIGxldCB1cyBza2lwIHRoZSB1bmludGVyZXN0aW5nCisjIGlkZW50aWZpZXIgcmVmZXJlbmNlcy4KKyMgbm9uS2V5UGF0IGlkZW50aWZpZXMgY2hhcmFjdGVycyB3aGljaCBtYXkgbGVnYWxseSBwcmVjZWRlCisjIGEga2V5d29yZCBwYXR0ZXJuLgorbm9uS2V5UGF0ID0gIlwoXlx8W15hLXpBLVowLTlfLlwiJ11cKSIKKwora2V5UGF0ID0gbm9uS2V5UGF0ICsgIlwoIgorZm9yIGtleXdvcmQgaW4ga2V5d29yZHNMaXN0OgorCWtleVBhdCA9IGtleVBhdCArIGtleXdvcmQgKyAiXHwiCitrZXlQYXQgPSBrZXlQYXRbOi0yXSArICJcKSIgKyBub25LZXlQYXQKKworbWF0Y2hQYXQgPSBrZXlQYXQgKyAiXHwiICsgY29tbWVudFBhdCArICJcfCIgKyB0cmlwbGVRdW90ZVBhdCArICJcfCIgKyBxdW90ZVBhdAorbWF0Y2hSRSA9IHJlZ2V4LmNvbXBpbGUobWF0Y2hQYXQpCisKK2lkS2V5UGF0ID0gIlsgXHRdKltBLVphLXpfXVtBLVphLXpfMC05Ll0qIgkjIElkZW50IHcuIGxlYWRpbmcgd2hpdGVzcGFjZS4KK2lkUkUgPSByZWdleC5jb21waWxlKGlkS2V5UGF0KQorCisKK2RlZiBmb250aWZ5KHB5dGV4dCwgc2VhcmNoZnJvbSA9IDAsIHNlYXJjaHRvID0gTm9uZSk6CisJaWYgc2VhcmNodG8gaXMgTm9uZToKKwkJc2VhcmNodG8gPSBsZW4ocHl0ZXh0KQorCSMgQ2FjaGUgYSBmZXcgYXR0cmlidXRlcyBmb3IgcXVpY2tlciByZWZlcmVuY2UuCisJc2VhcmNoID0gbWF0Y2hSRS5zZWFyY2gKKwlncm91cCA9IG1hdGNoUkUuZ3JvdXAKKwlpZFNlYXJjaCA9IGlkUkUuc2VhcmNoCisJaWRHcm91cCA9IGlkUkUuZ3JvdXAKKwkKKwl0YWdzID0gW10KKwl0YWdzX2FwcGVuZCA9IHRhZ3MuYXBwZW5kCisJY29tbWVudFRhZyA9ICdjb21tZW50JworCXN0cmluZ1RhZyA9ICdzdHJpbmcnCisJa2V5d29yZFRhZyA9ICdrZXl3b3JkJworCWlkZW50aWZpZXJUYWcgPSAnaWRlbnRpZmllcicKKwkKKwlzdGFydCA9IDAKKwllbmQgPSBzZWFyY2hmcm9tCisJd2hpbGUgMToKKwkJc3RhcnQgPSBzZWFyY2gocHl0ZXh0LCBlbmQpCisJCWlmIHN0YXJ0IDwgMCBvciBzdGFydCA+PSBzZWFyY2h0bzoKKwkJCWJyZWFrCSMgRVhJVCBMT09QCisJCW1hdGNoID0gZ3JvdXAoMCkKKwkJZW5kID0gc3RhcnQgKyBsZW4obWF0Y2gpCisJCWMgPSBtYXRjaFswXQorCQlpZiBjIG5vdCBpbiAiIydcIiI6CisJCQkjIE11c3QgaGF2ZSBtYXRjaGVkIGEga2V5d29yZC4KKwkJCWlmIHN0YXJ0IDw+IHNlYXJjaGZyb206CisJCQkJIyB0aGVyZSdzIHN0aWxsIGEgcmVkdW5kYW50IGNoYXIgYmVmb3JlIGFuZCBhZnRlciBpdCwgc3RyaXAhCisJCQkJbWF0Y2ggPSBtYXRjaFsxOi0xXQorCQkJCXN0YXJ0ID0gc3RhcnQgKyAxCisJCQllbHNlOgorCQkJCSMgdGhpcyBpcyB0aGUgZmlyc3Qga2V5d29yZCBpbiB0aGUgdGV4dC4KKwkJCQkjIE9ubHkgYSBzcGFjZSBhdCB0aGUgZW5kLgorCQkJCW1hdGNoID0gbWF0Y2hbOi0xXQorCQkJZW5kID0gZW5kIC0gMQorCQkJdGFnc19hcHBlbmQoKGtleXdvcmRUYWcsIHN0YXJ0LCBlbmQsIE5vbmUpKQorCQkJIyBJZiB0aGlzIHdhcyBhIGRlZmluaW5nIGtleXdvcmQsIGxvb2sgYWhlYWQgdG8gdGhlCisJCQkjIGZvbGxvd2luZyBpZGVudGlmaWVyLgorCQkJaWYgbWF0Y2ggaW4gWyJkZWYiLCAiY2xhc3MiXToKKwkJCQlzdGFydCA9IGlkU2VhcmNoKHB5dGV4dCwgZW5kKQorCQkJCWlmIHN0YXJ0ID09IGVuZDoKKwkJCQkJbWF0Y2ggPSBpZEdyb3VwKDApCisJCQkJCWVuZCA9IHN0YXJ0ICsgbGVuKG1hdGNoKQorCQkJCQl0YWdzX2FwcGVuZCgoaWRlbnRpZmllclRhZywgc3RhcnQsIGVuZCwgTm9uZSkpCisJCWVsaWYgYyA9PSAiIyI6CisJCQl0YWdzX2FwcGVuZCgoY29tbWVudFRhZywgc3RhcnQsIGVuZCwgTm9uZSkpCisJCWVsc2U6CisJCQl0YWdzX2FwcGVuZCgoc3RyaW5nVGFnLCBzdGFydCwgZW5kLCBOb25lKSkKKwlyZXR1cm4gdGFncworCisKK2RlZiB0ZXN0KHBhdGgpOgorCWYgPSBvcGVuKHBhdGgpCisJdGV4dCA9IGYucmVhZCgpCisJZi5jbG9zZSgpCisJdGFncyA9IGZvbnRpZnkodGV4dCkKKwlmb3IgdGFnLCBzdGFydCwgZW5kLCBzdWJsaXN0IGluIHRhZ3M6CisJCXByaW50IHRhZywgYHRleHRbc3RhcnQ6ZW5kXWAKZGlmZiAtLWdpdCBhL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9QeUludGVyYWN0aXZlLnB5IGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1B5SW50ZXJhY3RpdmUucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZGM3NWU0YgotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9QeUludGVyYWN0aXZlLnB5CkBAIC0wLDAgKzEsMTE1IEBACitpbXBvcnQgc3RyaW5nCitpbXBvcnQgc3lzCitpbXBvcnQgdHJhY2ViYWNrCisKKwordHJ5OgorCXN5cy5wczEKK2V4Y2VwdCBBdHRyaWJ1dGVFcnJvcjoKKwlzeXMucHMxID0gIj4+PiAiCit0cnk6CisJc3lzLnBzMgorZXhjZXB0IEF0dHJpYnV0ZUVycm9yOgorCXN5cy5wczIgPSAiLi4uICIKKworCitkZWYgcHJpbnRfZXhjKGxpbWl0PU5vbmUsIGZpbGU9Tm9uZSk6CisJaWYgbm90IGZpbGU6CisJCWZpbGUgPSBzeXMuc3RkZXJyCisJIyB3ZSdyZSBnb2luZyB0byBza2lwIHRoZSBvdXRlcm1vc3QgdHJhY2ViYWNrIG9iamVjdCwgd2UgZG9uJ3QKKwkjIHdhbnQgcGVvcGxlIHRvIHNlZSB0aGUgbGluZSB3aGljaCBleGNlY3V0ZWQgdGhlaXIgY29kZS4KKwl0YiA9IHN5cy5leGNfdHJhY2ViYWNrCisJaWYgdGI6CisJCXRiID0gdGIudGJfbmV4dAorCXRyeToKKwkJc3lzLmxhc3RfdHlwZSA9IHN5cy5leGNfdHlwZQorCQlzeXMubGFzdF92YWx1ZSA9IHN5cy5leGNfdmFsdWUKKwkJc3lzLmxhc3RfdHJhY2ViYWNrID0gdGIKKwkJdHJhY2ViYWNrLnByaW50X2V4Y2VwdGlvbihzeXMubGFzdF90eXBlLCBzeXMubGFzdF92YWx1ZSwgCisJCQkJCXN5cy5sYXN0X3RyYWNlYmFjaywgbGltaXQsIGZpbGUpCisJZXhjZXB0OgorCQlwcmludCAnLS0tIGhvbGEhIC0tLScKKwkJdHJhY2ViYWNrLnByaW50X2V4Y2VwdGlvbihzeXMuZXhjX3R5cGUsIHN5cy5leGNfdmFsdWUsIAorCQkJCQlzeXMuZXhjX3RyYWNlYmFjaywgbGltaXQsIGZpbGUpCisKKworY2xhc3MgUHlJbnRlcmFjdGl2ZToKKwkKKwlkZWYgX19pbml0X18oc2VsZik6CisJCXNlbGYuX3B5YnVmID0gIiIKKwkKKwlkZWYgZXhlY3V0ZWxpbmUoc2VsZiwgc3R1ZmYsIG91dCA9IE5vbmUsIGVudiA9IE5vbmUpOgorCQlpZiBlbnYgaXMgTm9uZToKKwkJCWltcG9ydCBfX21haW5fXworCQkJZW52ID0gX19tYWluX18uX19kaWN0X18KKwkJaWYgb3V0OgorCQkJc2F2ZWVyciwgc2F2ZW91dCA9IHN5cy5zdGRlcnIsIHN5cy5zdGRvdXQKKwkJCXN5cy5zdGRlcnIgPSBzeXMuc3Rkb3V0ID0gb3V0CisJCXRyeToKKwkJCWlmIHNlbGYuX3B5YnVmOgorCQkJCXNlbGYuX3B5YnVmID0gc2VsZi5fcHlidWYgKyAnXG4nICsgc3R1ZmYKKwkJCWVsc2U6CisJCQkJc2VsZi5fcHlidWYgPSBzdHVmZgorCQkJCisJCQkjIENvbXBpbGUgdGhyZWUgdGltZXM6IGFzIGlzLCB3aXRoIFxuLCBhbmQgd2l0aCBcblxuIGFwcGVuZGVkLgorCQkJIyBJZiBpdCBjb21waWxlcyBhcyBpcywgaXQncyBjb21wbGV0ZS4gIElmIGl0IGNvbXBpbGVzIHdpdGgKKwkJCSMgb25lIFxuIGFwcGVuZGVkLCB3ZSBleHBlY3QgbW9yZS4gIElmIGl0IGRvZXNuJ3QgY29tcGlsZQorCQkJIyBlaXRoZXIgd2F5LCB3ZSBjb21wYXJlIHRoZSBlcnJvciB3ZSBnZXQgd2hlbiBjb21waWxpbmcgd2l0aAorCQkJIyBcbiBvciBcblxuIGFwcGVuZGVkLiAgSWYgdGhlIGVycm9ycyBhcmUgdGhlIHNhbWUsIHRoZSBjb2RlCisJCQkjIGlzIGJyb2tlbi4gIEJ1dCBpZiB0aGUgZXJyb3JzIGFyZSBkaWZmZXJlbnQsIHdlIGV4cGVjdCBtb3JlLgorCQkJIyBOb3QgaW50dWl0aXZlOyBub3QgZXZlbiBndWFyYW50ZWVkIHRvIGhvbGQgaW4gZnV0dXJlCisJCQkjIHJlbGVhc2VzOyBidXQgdGhpcyBtYXRjaGVzIHRoZSBjb21waWxlcidzIGJlaGF2aW9yIGluIFB5dGhvbgorCQkJIyAxLjQgYW5kIDEuNS4KKwkJCWVyciA9IGVycjEgPSBlcnIyID0gTm9uZQorCQkJY29kZSA9IGNvZGUxID0gY29kZTIgPSBOb25lCisJCQkKKwkJCSMgcXVpY2tseSBnZXQgb3V0IG9mIGhlcmUgd2hlbiB0aGUgbGluZSBpcyAnZW1wdHknIG9yIGlzIGEgY29tbWVudAorCQkJc3RyaXBwZWQgPSBzdHJpbmcuc3RyaXAoc2VsZi5fcHlidWYpCisJCQlpZiBub3Qgc3RyaXBwZWQgb3Igc3RyaXBwZWRbMF0gPT0gJyMnOgorCQkJCXNlbGYuX3B5YnVmID0gJycKKwkJCQlzeXMuc3Rkb3V0LndyaXRlKHN5cy5wczEpCisJCQkJc3lzLnN0ZG91dC5mbHVzaCgpCisJCQkJcmV0dXJuCisJCQkKKwkJCXRyeToKKwkJCQljb2RlID0gY29tcGlsZShzZWxmLl9weWJ1ZiwgIjxpbnB1dD4iLCAic2luZ2xlIikKKwkJCWV4Y2VwdCBTeW50YXhFcnJvciwgZXJyOgorCQkJCXBhc3MKKwkJCWV4Y2VwdDoKKwkJCQkjIE92ZXJmbG93RXJyb3IuIE1vcmU/CisJCQkJcHJpbnRfZXhjKCkKKwkJCQlzZWxmLl9weWJ1ZiA9ICIiCisJCQkJc3lzLnN0ZG91dC53cml0ZShzeXMucHMxKQorCQkJCXN5cy5zdGRvdXQuZmx1c2goKQorCQkJCXJldHVybgorCQkJCisJCQl0cnk6CisJCQkJY29kZTEgPSBjb21waWxlKHNlbGYuX3B5YnVmICsgIlxuIiwgIjxpbnB1dD4iLCAic2luZ2xlIikKKwkJCWV4Y2VwdCBTeW50YXhFcnJvciwgZXJyMToKKwkJCQlwYXNzCisJCQkKKwkJCXRyeToKKwkJCQljb2RlMiA9IGNvbXBpbGUoc2VsZi5fcHlidWYgKyAiXG5cbiIsICI8aW5wdXQ+IiwgInNpbmdsZSIpCisJCQlleGNlcHQgU3ludGF4RXJyb3IsIGVycjI6CisJCQkJcGFzcworCQkJCisJCQlpZiBjb2RlOgorCQkJCXRyeToKKwkJCQkJZXhlYyBjb2RlIGluIGVudgorCQkJCWV4Y2VwdDoKKwkJCQkJcHJpbnRfZXhjKCkKKwkJCQlzZWxmLl9weWJ1ZiA9ICIiCisJCQllbGlmIGNvZGUxOgorCQkJCXBhc3MKKwkJCWVsaWYgZXJyMSA9PSBlcnIyIG9yIChub3Qgc3R1ZmYgYW5kIHNlbGYuX3B5YnVmKToKKwkJCQlwcmludF9leGMoKQorCQkJCXNlbGYuX3B5YnVmID0gIiIKKwkJCWlmIHNlbGYuX3B5YnVmOgorCQkJCXN5cy5zdGRvdXQud3JpdGUoc3lzLnBzMikKKwkJCQlzeXMuc3Rkb3V0LmZsdXNoKCkKKwkJCWVsc2U6CisJCQkJc3lzLnN0ZG91dC53cml0ZShzeXMucHMxKQorCQkJCXN5cy5zdGRvdXQuZmx1c2goKQorCQlmaW5hbGx5OgorCQkJaWYgb3V0OgorCQkJCXN5cy5zdGRlcnIsIHN5cy5zdGRvdXQgPSBzYXZlZXJyLCBzYXZlb3V0CmRpZmYgLS1naXQgYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvU3BlY2lhbEtleXMucHkgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvU3BlY2lhbEtleXMucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTdlZTVkOAotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9TcGVjaWFsS2V5cy5weQpAQCAtMCwwICsxLDQ0IEBACitzcGFjZWtleQkJPSAnICcKK3JldHVybmtleSAJCT0gJ1xyJwordGFia2V5IAkJPSAnXHQnCitlbnRlcmtleSAJCT0gJ1wwMDMnCitiYWNrc3BhY2VrZXkgCT0gJ1wwMTAnCitkZWxldGVrZXkgCQk9ICdcMTc3JworCitoZWxwa2V5IAkJPSAnXDAwNScKKworbGVmdGFycm93a2V5IAk9ICdcMDM0JworcmlnaHRhcnJvd2tleSAJPSAnXDAzNScKK3VwYXJyb3drZXkgCQk9ICdcMDM2JworZG93bmFycm93a2V5IAk9ICdcMDM3JworYXJyb3drZXlzIAkJPSBbbGVmdGFycm93a2V5LCByaWdodGFycm93a2V5LCB1cGFycm93a2V5LCBkb3duYXJyb3drZXldCisKK3RvcGtleSAJCT0gJ1wwMDEnCitib3R0b21rZXkgCQk9ICdcMDA0JworcGFnZXVwa2V5IAkJPSAnXDAxMycKK3BhZ2Vkb3dua2V5IAk9ICdcMDE0Jworc2Nyb2xsa2V5cyAJCT0gW3RvcGtleSwgYm90dG9ta2V5LCBwYWdldXBrZXksIHBhZ2Vkb3dua2V5XQorCituYXZpZ2F0aW9ua2V5cyA9IGFycm93a2V5cyArIHNjcm9sbGtleXMKKwora2V5Y29kZXMgPSB7CisJInNwYWNlIgkJOiAnICcsCisJInJldHVybiIJCTogJ1xyJywKKwkidGFiIiAJCQk6ICdcdCcsCisJImVudGVyIiAJCTogJ1wwMDMnLAorCSJiYWNrc3BhY2UiCTogJ1wwMTAnLAorCSJkZWxldGUiCQk6ICdcMTc3JywKKwkiaGVscCIgCQk6ICdcMDA1JywKKwkibGVmdGFycm93IgkJOiAnXDAzNCcsCisJInJpZ2h0YXJyb3ciIAk6ICdcMDM1JywKKwkidXBhcnJvdyIgCQk6ICdcMDM2JywKKwkiZG93bmFycm93Igk6ICdcMDM3JywKKwkidG9wIiAJCQk6ICdcMDAxJywKKwkiYm90dG9tIiAJCTogJ1wwMDQnLAorCSJwYWdldXAiIAkJOiAnXDAxMycsCisJInBhZ2Vkb3duIiAJOiAnXDAxNCcKK30KKwora2V5bmFtZXMgPSB7fQorZm9yIGssIHYgaW4ga2V5Y29kZXMuaXRlbXMoKToKKwlrZXluYW1lc1t2XSA9IGsKZGlmZiAtLWdpdCBhL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XLnB5IGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1cucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMTYxZGRkNgotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XLnB5CkBAIC0wLDAgKzEsMzMgQEAKKyIiIldpZGdldHMgZm9yIHRoZSBNYWNpbnRvc2guIEJ1aWx0IG9uIHRvcCBvZiBGcmFtZVdvcmsiIiIKKworX192ZXJzaW9uX18gPSAiMC4xIgorCitmcm9tIFdiYXNlIGltcG9ydCAqCitmcm9tIFdjb250cm9scyBpbXBvcnQgKgorZnJvbSBXdGV4dCBpbXBvcnQgKgorZnJvbSBXbGlzdCBpbXBvcnQgKgorZnJvbSBXd2luZG93cyBpbXBvcnQgKgorZnJvbSBXbWVudXMgaW1wb3J0ICoKKworX2FwcGxpY2F0aW9uID0gTm9uZQorX3NpZ25hdHVyZSA9IE5vbmUKKworQWxlcnRFcnJvciA9ICdBbGVydEVycm9yJworCitkZWYgc2V0YXBwbGljYXRpb24oYXBwLCBzaWcpOgorCWdsb2JhbCBfYXBwbGljYXRpb24sIF9zaWduYXR1cmUKKwlfYXBwbGljYXRpb24gPSBhcHAKKwlfc2lnbmF0dXJlID0gc2lnCisKK2RlZiBnZXRhcHBsaWNhdGlvbigpOgorCWlmIF9hcHBsaWNhdGlvbiBpcyBOb25lOgorCQlyYWlzZSBXaWRnZXRzRXJyb3IsICdXIG5vdCBwcm9wZXJseSBpbml0aWFsaXplZDogdW5rbm93biBBcHBsaWNhdGlvbicKKwlyZXR1cm4gX2FwcGxpY2F0aW9uCisKK2RlZiBNZXNzYWdlKHRleHQpOgorCWltcG9ydCBFYXN5RGlhbG9ncywgUWQKKwlRZC5Jbml0Q3Vyc29yKCkKKwlpZiB0ZXh0OgorCQlFYXN5RGlhbG9ncy5NZXNzYWdlKHRleHQpCisJZWxzZToKKwkJRWFzeURpYWxvZ3MuTWVzc2FnZSgnPEFsZXJ0IHRleHQgbm90IHNwZWNpZmllZD4nKQpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1dGcmFtZVdvcmtQYXRjaC5weSBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XRnJhbWVXb3JrUGF0Y2gucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMjY3ZDhhYwotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XRnJhbWVXb3JrUGF0Y2gucHkKQEAgLTAsMCArMSwzNDQgQEAKK2ltcG9ydCBGcmFtZVdvcmsKK2ltcG9ydCBXaW4KK2ltcG9ydCBRZAoraW1wb3J0IE1hY09TCitpbXBvcnQgRXZlbnRzCitpbXBvcnQgdHJhY2ViYWNrCitmcm9tIHR5cGVzIGltcG9ydCAqCisKK2ltcG9ydCBNZW51OyBNZW51VG9vbGJveCA9IE1lbnU7IGRlbCBNZW51CisKKworY2xhc3MgQXBwbGljYXRpb24oRnJhbWVXb3JrLkFwcGxpY2F0aW9uKToKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgc2lnbmF0dXJlID0gJ1B5dGgnKToKKwkJaW1wb3J0IFcKKwkJVy5zZXRhcHBsaWNhdGlvbihzZWxmLCBzaWduYXR1cmUpCisJCUZyYW1lV29yay5BcHBsaWNhdGlvbi5fX2luaXRfXyhzZWxmKQorCQlzZWxmLl9zdXNwZW5kZWQgPSAwCisJCXNlbGYucXVpdHRpbmcgPSAwCisJCXNlbGYuZGVidWdnZXJfcXVpdHRpbmcgPSAxCisJCXNlbGYuRGVidWdnZXJRdWl0ID0gJ0RlYnVnZ2VyUXVpdER1bW15RXhjZXB0aW9uJworCQorCWRlZiBtYWlubG9vcChzZWxmLCBtYXNrID0gRnJhbWVXb3JrLmV2ZXJ5RXZlbnQsIHdhaXQgPSAwKToKKwkJaW1wb3J0IFcKKwkJc2VsZi5xdWl0dGluZyA9IDAKKwkJc2F2ZXlpZWxkID0gTWFjT1MuRW5hYmxlQXBwc3dpdGNoKC0xKQorCQl0cnk6CisJCQl3aGlsZSBub3Qgc2VsZi5xdWl0dGluZzoKKwkJCQl0cnk6CisJCQkJCXNlbGYuZG8xZXZlbnQobWFzaywgd2FpdCkKKwkJCQlleGNlcHQgVy5BbGVydEVycm9yLCBkZXRhaWw6CisJCQkJCU1hY09TLkVuYWJsZUFwcHN3aXRjaCgtMSkKKwkJCQkJVy5NZXNzYWdlKGRldGFpbCkKKwkJCQlleGNlcHQgc2VsZi5EZWJ1Z2dlclF1aXQ6CisJCQkJCU1hY09TLkVuYWJsZUFwcHN3aXRjaCgtMSkKKwkJCQlleGNlcHQ6CisJCQkJCU1hY09TLkVuYWJsZUFwcHN3aXRjaCgtMSkKKwkJCQkJaW1wb3J0IFB5RWRpdAorCQkJCQlQeUVkaXQudHJhY2ViYWNrd2luZG93LnRyYWNlYmFjaygpCisJCWZpbmFsbHk6CisJCQlNYWNPUy5FbmFibGVBcHBzd2l0Y2goMSkKKwkKKwlkZWYgZGVidWdnZXJfbWFpbmxvb3Aoc2VsZiwgbWFzayA9IEZyYW1lV29yay5ldmVyeUV2ZW50LCB3YWl0ID0gMCk6CisJCWltcG9ydCBXCisJCXNlbGYuZGVidWdnZXJfcXVpdHRpbmcgPSAwCisJCXNhdmV5aWVsZCA9IE1hY09TLkVuYWJsZUFwcHN3aXRjaCgtMSkKKwkJdHJ5OgorCQkJd2hpbGUgbm90IHNlbGYucXVpdHRpbmcgYW5kIG5vdCBzZWxmLmRlYnVnZ2VyX3F1aXR0aW5nOgorCQkJCXRyeToKKwkJCQkJc2VsZi5kbzFldmVudChtYXNrLCB3YWl0KQorCQkJCWV4Y2VwdCBXLkFsZXJ0RXJyb3IsIGRldGFpbDoKKwkJCQkJVy5NZXNzYWdlKGRldGFpbCkKKwkJCQlleGNlcHQ6CisJCQkJCWltcG9ydCBQeUVkaXQKKwkJCQkJUHlFZGl0LnRyYWNlYmFja3dpbmRvdy50cmFjZWJhY2soKQorCQlmaW5hbGx5OgorCQkJTWFjT1MuRW5hYmxlQXBwc3dpdGNoKHNhdmV5aWVsZCkKKwkKKwlkZWYgaWRsZShzZWxmLCBldmVudCk6CisJCWlmIG5vdCBzZWxmLl9zdXNwZW5kZWQ6CisJCQlpZiBub3Qgc2VsZi5kb19mcm9udFdpbmRvd01ldGhvZCgiaWRsZSIsIGV2ZW50KToKKwkJCQlRZC5Jbml0Q3Vyc29yKCkKKwkKKwlkZWYgZG9fZnJvbnRXaW5kb3dNZXRob2Qoc2VsZiwgYXR0ciwgKmFyZ3MpOgorCQl3aWQgPSBXaW4uRnJvbnRXaW5kb3coKQorCQlpZiB3aWQgYW5kIHNlbGYuX3dpbmRvd3MuaGFzX2tleSh3aWQpOgorCQkJd2luZG93ID0gc2VsZi5fd2luZG93c1t3aWRdCisJCQlpZiBoYXNhdHRyKHdpbmRvdywgYXR0cik6CisJCQkJaGFuZGxlciA9IGdldGF0dHIod2luZG93LCBhdHRyKQorCQkJCWFwcGx5KGhhbmRsZXIsIGFyZ3MpCisJCQkJcmV0dXJuIDEKKwkKKwlkZWYgYXBwZW5kd2luZG93KHNlbGYsIHdpZCwgd2luZG93KToKKwkJc2VsZi5fd2luZG93c1t3aWRdID0gd2luZG93CisJCXNlbGYubWFrZW9wZW53aW5kb3dzbWVudSgpCisJCQorCWRlZiByZW1vdmV3aW5kb3coc2VsZiwgd2lkKToKKwkJZGVsIHNlbGYuX3dpbmRvd3Nbd2lkXQorCQlzZWxmLm1ha2VvcGVud2luZG93c21lbnUoKQorCQorCWRlZiBkb19rZXkoc2VsZiwgZXZlbnQpOgorCQkod2hhdCwgbWVzc2FnZSwgd2hlbiwgd2hlcmUsIG1vZGlmaWVycykgPSBldmVudAorCQljaCA9IGNocihtZXNzYWdlICYgRnJhbWVXb3JrLmNoYXJDb2RlTWFzaykKKwkJcmVzdCA9IG1lc3NhZ2UgJiB+RnJhbWVXb3JrLmNoYXJDb2RlTWFzaworCQl3aWQgPSBXaW4uRnJvbnRXaW5kb3coKQorCQlpZiBtb2RpZmllcnMgJiBGcmFtZVdvcmsuY21kS2V5OgorCQkJaWYgd2lkIGFuZCBzZWxmLl93aW5kb3dzLmhhc19rZXkod2lkKToKKwkJCQlzZWxmLmNoZWNrbWVudXMoc2VsZi5fd2luZG93c1t3aWRdKQorCQkJZWxzZToKKwkJCQlzZWxmLmNoZWNrbWVudXMoTm9uZSkKKwkJCWV2ZW50ID0gKHdoYXQsIG9yZChjaCkgfCByZXN0LCB3aGVuLCB3aGVyZSwgbW9kaWZpZXJzKQorCQkJcmVzdWx0ID0gTWVudVRvb2xib3guTWVudUtleShvcmQoY2gpKQorCQkJaWQgPSAocmVzdWx0Pj4xNikgJiAweGZmZmYJIyBIaSB3b3JkCisJCQlpdGVtID0gcmVzdWx0ICYgMHhmZmZmCQkjIExvIHdvcmQKKwkJCWlmIGlkOgorCQkJCXNlbGYuZG9fcmF3bWVudShpZCwgaXRlbSwgTm9uZSwgZXZlbnQpCisJCQkJcmV0dXJuCSMgaGVyZSEgd2UgaGFkIGEgbWVudWtleSEgCisJCQkjZWxzZToKKwkJCSMJcHJpbnQgIlhYWCBDb21tYW5kLSIgK2BjaGAKKwkJIyBTZWUgd2hldGhlciB0aGUgZnJvbnQgd2luZG93IHdhbnRzIGl0CisJCWlmIHdpZCBhbmQgc2VsZi5fd2luZG93cy5oYXNfa2V5KHdpZCk6CisJCQl3aW5kb3cgPSBzZWxmLl93aW5kb3dzW3dpZF0KKwkJCXRyeToKKwkJCQlkb19jaGFyID0gd2luZG93LmRvX2NoYXIKKwkJCWV4Y2VwdCBBdHRyaWJ1dGVFcnJvcjoKKwkJCQlkb19jaGFyID0gc2VsZi5kb19jaGFyCisJCQlkb19jaGFyKGNoLCBldmVudCkKKwkJIyBlbHNlIGl0IHdhc24ndCBmb3IgdXMsIHNpZ2guLi4KKwkKKwlkZWYgZG9faW5NZW51QmFyKHNlbGYsIHBhcnRjb2RlLCB3aW5kb3csIGV2ZW50KToKKwkJUWQuSW5pdEN1cnNvcigpCisJCSh3aGF0LCBtZXNzYWdlLCB3aGVuLCB3aGVyZSwgbW9kaWZpZXJzKSA9IGV2ZW50CisJCXNlbGYuY2hlY2tvcGVud2luZG93c21lbnUoKQorCQl3aWQgPSBXaW4uRnJvbnRXaW5kb3coKQorCQlpZiB3aWQgYW5kIHNlbGYuX3dpbmRvd3MuaGFzX2tleSh3aWQpOgorCQkJc2VsZi5jaGVja21lbnVzKHNlbGYuX3dpbmRvd3Nbd2lkXSkKKwkJZWxzZToKKwkJCXNlbGYuY2hlY2ttZW51cyhOb25lKQorCQlyZXN1bHQgPSBNZW51VG9vbGJveC5NZW51U2VsZWN0KHdoZXJlKQorCQlpZCA9IChyZXN1bHQ+PjE2KSAmIDB4ZmZmZgkjIEhpIHdvcmQKKwkJaXRlbSA9IHJlc3VsdCAmIDB4ZmZmZgkJIyBMbyB3b3JkCisJCXNlbGYuZG9fcmF3bWVudShpZCwgaXRlbSwgd2luZG93LCBldmVudCkKKwkKKwlkZWYgZG9fdXBkYXRlRXZ0KHNlbGYsIGV2ZW50KToKKwkJKHdoYXQsIG1lc3NhZ2UsIHdoZW4sIHdoZXJlLCBtb2RpZmllcnMpID0gZXZlbnQKKwkJd2lkID0gV2luLldoaWNoV2luZG93KG1lc3NhZ2UpCisJCWlmIHdpZCBhbmQgc2VsZi5fd2luZG93cy5oYXNfa2V5KHdpZCk6CisJCQl3aW5kb3cgPSBzZWxmLl93aW5kb3dzW3dpZF0KKwkJCXdpbmRvdy5kb19yYXd1cGRhdGUod2lkLCBldmVudCkKKwkJZWxzZToKKwkJCWlmIHdpZDoKKwkJCQl3aWQuSGlkZVdpbmRvdygpCisJCQkJaW1wb3J0IHN5cworCQkJCXN5cy5zdGRlcnIud3JpdGUoIlhYWCBraWxsZWQgdW5rbm93biAoY3Jhc2hlZD8pIFB5dGhvbiB3aW5kb3cuXG4iKQorCQkJZWxzZToKKwkJCQlNYWNPUy5IYW5kbGVFdmVudChldmVudCkKKwkKKwlkZWYgc3VzcGVuZHJlc3VtZShzZWxmLCBvbm9mZik6CisJCXBhc3MKKwkKKwlkZWYgZG9fc3VzcGVuZHJlc3VtZShzZWxmLCBldmVudCk6CisJCSMgSXMgdGhpcyBhIGdvb2QgaWRlYT8/PworCQkod2hhdCwgbWVzc2FnZSwgd2hlbiwgd2hlcmUsIG1vZGlmaWVycykgPSBldmVudAorCQlzZWxmLl9zdXNwZW5kZWQgPSBub3QgbWVzc2FnZSAmIDEKKwkJc2VsZi5zdXNwZW5kcmVzdW1lKG1lc3NhZ2UgJiAxKQorCQl3ID0gV2luLkZyb250V2luZG93KCkKKwkJaWYgdzoKKwkJCSMgWFhYWCBJbmNvcnJlY3QsIHNob3VsZCBzdHVmZiB3aW5kb3dwdHIgaW50byBtZXNzYWdlIGZpZWxkCisJCQluZXYgPSAoRXZlbnRzLmFjdGl2YXRlRXZ0LCB3LCB3aGVuLCB3aGVyZSwgbWVzc2FnZSYxKQorCQkJc2VsZi5kb19hY3RpdmF0ZUV2dChuZXYpCisJCisJZGVmIGNoZWNrb3BlbndpbmRvd3NtZW51KHNlbGYpOgorCQlpZiBzZWxmLl9vcGVud2luZG93c2NoZWNrbWFyazoKKwkJCXNlbGYub3BlbndpbmRvd3NtZW51Lm1lbnUuQ2hlY2tJdGVtKHNlbGYuX29wZW53aW5kb3dzY2hlY2ttYXJrLCAwKQorCQl3aW5kb3cgPSBXaW4uRnJvbnRXaW5kb3coKQorCQlpZiB3aW5kb3c6CisJCQlmb3IgaXRlbSwgd2lkIGluIHNlbGYuX29wZW53aW5kb3dzLml0ZW1zKCk6CisJCQkJaWYgd2lkID09IHdpbmRvdzoKKwkJCQkJI3NlbGYucHl0aG9ud2luZG93c21lbnVpdGVtLmNoZWNrKDEpCisJCQkJCXNlbGYub3BlbndpbmRvd3NtZW51Lm1lbnUuQ2hlY2tJdGVtKGl0ZW0sIDEpCisJCQkJCXNlbGYuX29wZW53aW5kb3dzY2hlY2ttYXJrID0gaXRlbQorCQkJCQlicmVhaworCQllbHNlOgorCQkJc2VsZi5fb3BlbndpbmRvd3NjaGVja21hcmsgPSAwCisJCSNpZiBzZWxmLl9vcGVud2luZG93czoKKwkJIwlzZWxmLnB5dGhvbndpbmRvd3NtZW51aXRlbS5lbmFibGUoMSkKKwkJI2Vsc2U6CisJCSMJc2VsZi5weXRob253aW5kb3dzbWVudWl0ZW0uZW5hYmxlKDApCisJCisJZGVmIGNoZWNrbWVudXMoc2VsZiwgd2luZG93KToKKwkJZm9yIGl0ZW0gaW4gc2VsZi5fbWVudXN0b2NoZWNrOgorCQkJY2FsbGJhY2sgPSBpdGVtLm1lbnUuaXRlbXNbaXRlbS5pdGVtLTFdWzJdCisJCQlpZiB0eXBlKGNhbGxiYWNrKSA8PiBTdHJpbmdUeXBlOgorCQkJCWl0ZW0uZW5hYmxlKDEpCisJCQllbGlmIGhhc2F0dHIod2luZG93LCAiZG9tZW51XyIgKyBjYWxsYmFjayk6CisJCQkJaWYgaGFzYXR0cih3aW5kb3csICJjYW5fIiArIGNhbGxiYWNrKToKKwkJCQkJY2FuaGFuZGxlciA9IGdldGF0dHIod2luZG93LCAiY2FuXyIgKyBjYWxsYmFjaykKKwkJCQkJaWYgY2FuaGFuZGxlcihpdGVtKToKKwkJCQkJCWl0ZW0uZW5hYmxlKDEpCisJCQkJCWVsc2U6CisJCQkJCQlpdGVtLmVuYWJsZSgwKQorCQkJCWVsc2U6CisJCQkJCWl0ZW0uZW5hYmxlKDEpCisJCQllbHNlOgorCQkJCWl0ZW0uZW5hYmxlKDApCisJCisJZGVmIG1ha2VtZW51YmFyKHNlbGYpOgorCQlzZWxmLm1lbnViYXIgPSBNZW51QmFyKHNlbGYpCisJCUZyYW1lV29yay5BcHBsZU1lbnUoc2VsZi5tZW51YmFyLCBzZWxmLmdldGFib3V0dGV4dCgpLCBzZWxmLmRvX2Fib3V0KQorCQlzZWxmLm1ha2V1c2VybWVudXMoKQorCisJZGVmIHNjcmlwdHN3YWxrKHNlbGYsIHRvcCwgbWVudSk6CisJCWltcG9ydCBvcywgbWFjZnMsIHN0cmluZworCQl0cnk6CisJCQluYW1lcyA9IG9zLmxpc3RkaXIodG9wKQorCQlleGNlcHQgb3MuZXJyb3I6CisJCQlGcmFtZVdvcmsuTWVudUl0ZW0obWVudSwgJyhTY3JpcHRzIEZvbGRlciBub3QgZm91bmQpJywgTm9uZSwgTm9uZSkKKwkJCXJldHVybgorCQlmb3IgbmFtZSBpbiBuYW1lczoKKwkJCXBhdGggPSBvcy5wYXRoLmpvaW4odG9wLCBuYW1lKQorCQkJbmFtZSA9IHN0cmluZy5zdHJpcChuYW1lKQorCQkJaWYgbmFtZVstMzpdID09ICctLS0nOgorCQkJCW1lbnUuYWRkc2VwYXJhdG9yKCkKKwkJCWVsaWYgb3MucGF0aC5pc2RpcihwYXRoKToKKwkJCQlzdWJtZW51ID0gRnJhbWVXb3JrLlN1Yk1lbnUobWVudSwgbmFtZSkKKwkJCQlzZWxmLnNjcmlwdHN3YWxrKHBhdGgsIHN1Ym1lbnUpCisJCQllbHNlOgorCQkJCWZzcyA9IG1hY2ZzLkZTU3BlYyhwYXRoKQorCQkJCWNyZWF0b3IsIHR5cGUgPSBmc3MuR2V0Q3JlYXRvclR5cGUoKQorCQkJCWlmIHR5cGUgPT0gJ1RFWFQnOgorCQkJCQlpZiBuYW1lWy0zOl0gPT0gJy5weSc6CisJCQkJCQluYW1lID0gbmFtZVs6LTNdCisJCQkJCWl0ZW0gPSBGcmFtZVdvcmsuTWVudUl0ZW0obWVudSwgbmFtZSwgTm9uZSwgc2VsZi5kb21lbnVfc2NyaXB0KQorCQkJCQlzZWxmLl9zY3JpcHRzWyhtZW51LmlkLCBpdGVtLml0ZW0pXSA9IHBhdGgKKwkKKwlkZWYgZG9tZW51X3NjcmlwdChzZWxmLCBpZCwgaXRlbSwgd2luZG93LCBldmVudCk6CisJCSh3aGF0LCBtZXNzYWdlLCB3aGVuLCB3aGVyZSwgbW9kaWZpZXJzKSA9IGV2ZW50CisJCXBhdGggPSBzZWxmLl9zY3JpcHRzWyhpZCwgaXRlbSldCisJCWltcG9ydCBvcworCQlpZiBub3Qgb3MucGF0aC5leGlzdHMocGF0aCk6CisJCQlzZWxmLm1ha2VzY3JpcHRzbWVudSgpCisJCQlpbXBvcnQgVworCQkJcmFpc2UgVy5BbGVydEVycm9yLCAiRmlsZSBub3QgZm91bmQuIgorCQlpZiBtb2RpZmllcnMgJiBGcmFtZVdvcmsub3B0aW9uS2V5OgorCQkJc2VsZi5vcGVuc2NyaXB0KHBhdGgpCisJCWVsc2U6CisJCQlpbXBvcnQgVywgTWFjT1MsIHN5cworCQkJVy5TZXRDdXJzb3IoIndhdGNoIikKKwkJCXN5cy5hcmd2ID0gW3BhdGhdCisJCQkjY3dkID0gb3MuZ2V0Y3dkKCkKKwkJCSNvcy5jaGRpcihvcy5wYXRoLmRpcm5hbWUocGF0aCkgKyAnOicpCisJCQl0cnk6CisJCQkJIyB4eHggaWYgdGhlcmUgaXMgYSBzY3JpcHQgd2luZG93IGZvciB0aGlzIGZpbGUsCisJCQkJIyBleGVjIGluIHRoYXQgd2luZG93J3MgbmFtZXNwYWNlLgorCQkJCSMgeHh4IHdoYXQgdG8gZG8gd2hlbiBpdCdzIG5vdCBzYXZlZD8/PworCQkJCSMgcHJvbXQgdG8gc2F2ZT8KKwkJCQlNYWNPUy5FbmFibGVBcHBzd2l0Y2goMCkKKwkJCQlleGVjZmlsZShwYXRoLCB7J19fbmFtZV9fJzogJ19fbWFpbl9fJywgJ19fZmlsZV9fJzogcGF0aH0pCisJCQlleGNlcHQgVy5BbGVydEVycm9yLCBkZXRhaWw6CisJCQkJTWFjT1MuRW5hYmxlQXBwc3dpdGNoKC0xKQorCQkJCXJhaXNlIFcuQWxlcnRFcnJvciwgZGV0YWlsCisJCQlleGNlcHQgS2V5Ym9hcmRJbnRlcnJ1cHQ6CisJCQkJTWFjT1MuRW5hYmxlQXBwc3dpdGNoKC0xKQorCQkJZXhjZXB0OgorCQkJCU1hY09TLkVuYWJsZUFwcHN3aXRjaCgtMSkKKwkJCQlpbXBvcnQgUHlFZGl0CisJCQkJUHlFZGl0LnRyYWNlYmFja3dpbmRvdy50cmFjZWJhY2soMSkKKwkJCWVsc2U6CisJCQkJTWFjT1MuRW5hYmxlQXBwc3dpdGNoKC0xKQorCQkJI29zLmNoZGlyKGN3ZCkKKwkKKwlkZWYgb3BlbnNjcmlwdChzZWxmLCBmaWxlbmFtZSwgbGluZW5vID0gTm9uZSwgY2hhcm9mZnNldCA9IDApOgorCQlpbXBvcnQgb3MsIFB5RWRpdCwgVworCQllZGl0b3IgPSBzZWxmLmdldHNjcmlwdChmaWxlbmFtZSkKKwkJaWYgZWRpdG9yOgorCQkJZWRpdG9yLnNlbGVjdCgpCisJCWVsaWYgb3MucGF0aC5leGlzdHMoZmlsZW5hbWUpOgorCQkJZWRpdG9yID0gUHlFZGl0LkVkaXRvcihmaWxlbmFtZSkKKwkJZWxpZiBmaWxlbmFtZVstMzpdID09ICcucHknOgorCQkJaW1wb3J0IGltcAorCQkJbW9kbmFtZSA9IG9zLnBhdGguYmFzZW5hbWUoZmlsZW5hbWUpWzotM10KKwkJCXRyeToKKwkJCQlmLCBmaWxlbmFtZSwgKHN1ZmYsIG1vZGUsIGR1bW15KSA9IGltcC5maW5kX21vZHVsZShtb2RuYW1lKQorCQkJZXhjZXB0IEltcG9ydEVycm9yOgorCQkJCXJhaXNlIFcuQWxlcnRFcnJvciwgIkNhbrl0IGZpbmQgZmlsZSBmb3IgsyVzsiIgJSBtb2RuYW1lCisJCQllbHNlOgorCQkJCWYuY2xvc2UoKQorCQkJaWYgc3VmZiA9PSAnLnB5JzoKKwkJCQlzZWxmLm9wZW5zY3JpcHQoZmlsZW5hbWUsIGxpbmVubywgY2hhcm9mZnNldCkKKwkJCQlyZXR1cm4KKwkJCWVsc2U6CisJCQkJcmFpc2UgVy5BbGVydEVycm9yLCAiQ2FuuXQgZmluZCBmaWxlIGZvciCzJXOyIiAlIG1vZG5hbWUKKwkJZWxzZToKKwkJCXJhaXNlIFcuQWxlcnRFcnJvciwgIkNhbrl0IGZpbmQgZmlsZSCMJXO5IiAlIGZpbGVuYW1lCisJCWlmIGxpbmVubyBpcyBub3QgTm9uZToKKwkJCWVkaXRvci5zZWxlY3RsaW5lKGxpbmVubywgY2hhcm9mZnNldCkKKwkJcmV0dXJuIGVkaXRvcgorCQorCWRlZiBnZXRzY3JpcHQoc2VsZiwgZmlsZW5hbWUpOgorCQlpZiBmaWxlbmFtZVs6MV0gPT0gJzwnIGFuZCBmaWxlbmFtZVstMTpdID09ICc+JzoKKwkJCWZpbGVuYW1lID0gZmlsZW5hbWVbMTotMV0KKwkJaW1wb3J0IHN0cmluZworCQlsb3dwYXRoID0gc3RyaW5nLmxvd2VyKGZpbGVuYW1lKQorCQlmb3Igd2lkLCB3aW5kb3cgaW4gc2VsZi5fd2luZG93cy5pdGVtcygpOgorCQkJaWYgaGFzYXR0cih3aW5kb3csICJwYXRoIikgYW5kIGxvd3BhdGggPT0gc3RyaW5nLmxvd2VyKHdpbmRvdy5wYXRoKToKKwkJCQlyZXR1cm4gd2luZG93CisJCQllbGlmIGhhc2F0dHIod2luZG93LCAicGF0aCIpIGFuZCBmaWxlbmFtZSA9PSB3aWQuR2V0V1RpdGxlKCk6CisJCQkJcmV0dXJuIHdpbmRvdworCQorCWRlZiBnZXRwcmVmcyhzZWxmKToKKwkJaW1wb3J0IE1hY1ByZWZzCisJCXJldHVybiBNYWNQcmVmcy5HZXRQcmVmcyhzZWxmLnByZWZmaWxlcGF0aCkKKworCisKK2NsYXNzIE1lbnVCYXIoRnJhbWVXb3JrLk1lbnVCYXIpOgorCQorCXBvc3NpYmxlSURzID0gcmFuZ2UoMTAsIDI1NikKKwkKKwlkZWYgZ2V0bmV4dGlkKHNlbGYpOgorCQlpZCA9IHNlbGYucG9zc2libGVJRHNbMF0KKwkJZGVsIHNlbGYucG9zc2libGVJRHNbMF0KKwkJcmV0dXJuIGlkCisJCisJZGVmIF9faW5pdF9fKHNlbGYsIHBhcmVudCA9IE5vbmUpOgorCQlzZWxmLmJhciA9IE1lbnVUb29sYm94LkdldE1lbnVCYXIoKQorCQlNZW51VG9vbGJveC5DbGVhck1lbnVCYXIoKQorCQlzZWxmLm1lbnVzID0ge30KKwkJc2VsZi5wYXJlbnQgPSBwYXJlbnQKKwkKKwlkZWYgZGlzcGF0Y2goc2VsZiwgaWQsIGl0ZW0sIHdpbmRvdywgZXZlbnQpOgorCQlpZiBzZWxmLm1lbnVzLmhhc19rZXkoaWQpOgorCQkJc2VsZi5tZW51c1tpZF0uZGlzcGF0Y2goaWQsIGl0ZW0sIHdpbmRvdywgZXZlbnQpCisJCisJZGVmIGRlbG1lbnUoc2VsZiwgaWQpOgorCQlNZW51VG9vbGJveC5EZWxldGVNZW51KGlkKQorCQlpZiBpZCBpbiBzZWxmLnBvc3NpYmxlSURzOgorCQkJcHJpbnQgIlhYWCBkdXBsaWNhdGUgbWVudSBJRCEiLCBpZAorCQlzZWxmLnBvc3NpYmxlSURzLmFwcGVuZChpZCkKKwkKKworY2xhc3MgTWVudShGcmFtZVdvcmsuTWVudSk6CisJCisJZGVmIGRpc3BhdGNoKHNlbGYsIGlkLCBpdGVtLCB3aW5kb3csIGV2ZW50KToKKwkJdGl0bGUsIHNob3J0Y3V0LCBjYWxsYmFjaywga2luZCA9IHNlbGYuaXRlbXNbaXRlbS0xXQorCQlpZiB0eXBlKGNhbGxiYWNrKSA9PSBTdHJpbmdUeXBlOgorCQkJY2FsbGJhY2sgPSBzZWxmLl9nZXRtZW51aGFuZGxlcihjYWxsYmFjaykKKwkJaWYgY2FsbGJhY2s6CisJCQlpbXBvcnQgVworCQkJVy5DYWxsYmFja0NhbGwoY2FsbGJhY2ssIDAsIGlkLCBpdGVtLCB3aW5kb3csIGV2ZW50KQorCQorCWRlZiBfZ2V0bWVudWhhbmRsZXIoc2VsZiwgY2FsbGJhY2spOgorCQltZW51aGFuZGxlciA9IE5vbmUKKwkJd2lkID0gV2luLkZyb250V2luZG93KCkKKwkJaWYgd2lkIGFuZCBzZWxmLmJhci5wYXJlbnQuX3dpbmRvd3MuaGFzX2tleSh3aWQpOgorCQkJd2luZG93ID0gc2VsZi5iYXIucGFyZW50Ll93aW5kb3dzW3dpZF0KKwkJCWlmIGhhc2F0dHIod2luZG93LCAiZG9tZW51XyIgKyBjYWxsYmFjayk6CisJCQkJbWVudWhhbmRsZXIgPSBnZXRhdHRyKHdpbmRvdywgImRvbWVudV8iICsgY2FsbGJhY2spCisJCQllbGlmIGhhc2F0dHIoc2VsZi5iYXIucGFyZW50LCAiZG9tZW51XyIgKyBjYWxsYmFjayk6CisJCQkJbWVudWhhbmRsZXIgPSBnZXRhdHRyKHNlbGYuYmFyLnBhcmVudCwgImRvbWVudV8iICsgY2FsbGJhY2spCisJCWVsaWYgaGFzYXR0cihzZWxmLmJhci5wYXJlbnQsICJkb21lbnVfIiArIGNhbGxiYWNrKToKKwkJCW1lbnVoYW5kbGVyID0gZ2V0YXR0cihzZWxmLmJhci5wYXJlbnQsICJkb21lbnVfIiArIGNhbGxiYWNrKQorCQlyZXR1cm4gbWVudWhhbmRsZXIKKwpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1diYXNlLnB5IGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1diYXNlLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmJjZDc3ODkKLS0tIC9kZXYvbnVsbAorKysgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvV2Jhc2UucHkKQEAgLTAsMCArMSw2MTIgQEAKK2ltcG9ydCBRZAoraW1wb3J0IFdpbgoraW1wb3J0IFF1aWNrRHJhdworaW1wb3J0IEV2dAoraW1wb3J0IHN0cmluZworZnJvbSB0eXBlcyBpbXBvcnQgKgorZnJvbSBTcGVjaWFsS2V5cyBpbXBvcnQgKgoraW1wb3J0IHN5cworCitXaWRnZXRzRXJyb3IgPSAiV2lkZ2V0c0Vycm9yIgorCitERUJVRyA9IDAKKworY2xhc3MgV2lkZ2V0OgorCQorCV9zZWxlY3RhYmxlID0gMAorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBwb3NzaXplKToKKwkJc2VsZi5fd2lkZ2V0cyA9IFtdCisJCXNlbGYuX3dpZGdldHNkaWN0ID0ge30KKwkJc2VsZi5fcG9zc2l6ZSA9IHBvc3NpemUKKwkJc2VsZi5fYm91bmRzID0gTm9uZQorCQlzZWxmLl92aXNpYmxlID0gMQorCQlzZWxmLl9lbmFibGVkID0gMAorCQlzZWxmLl9zZWxlY3RlZCA9IDAKKwkJc2VsZi5fYWN0aXZhdGVkID0gMAorCQlzZWxmLl9jYWxsYmFjayA9IE5vbmUKKwkJc2VsZi5fcGFyZW50ID0gTm9uZQorCQlzZWxmLl9wYXJlbnR3aW5kb3cgPSBOb25lCisJCXNlbGYuX2JpbmRpbmdzID0ge30KKwkJc2VsZi5fYmFja2NvbG9yID0gTm9uZQorCQorCWRlZiBzaG93KHNlbGYsIG9ub2ZmKToKKwkJc2VsZi5TZXRQb3J0KCkKKwkJc2VsZi5fdmlzaWJsZSA9IG9ub2ZmCisJCXByaW50ICdCYWNrZ3JvdW5kJworCQlpZiBzZWxmLl92aXNpYmxlIGFuZCBzZWxmLl9iYWNrY29sb3I6CisJCQlwZW5zdGF0ZSA9IFFkLkdldFBlblN0YXRlKCkKKwkJCVFkLlJHQkZvcmVDb2xvcihzZWxmLl9iYWNrY29sb3IpCisJCQlRZC5GcmFtZVJlY3Qoc2VsZi5fYm91bmRzKQorCQkJUWQuUkdCRm9yZUNvbG9yKCgwLCAwLCAwKSkKKwkJCVFkLlNldFBlblN0YXRlKHBlbnN0YXRlKQorCQkJCisJCWZvciB3IGluIHNlbGYuX3dpZGdldHM6CisJCQl3LnNob3cob25vZmYpCisJCWlmIG9ub2ZmOgorCQkJc2VsZi5kcmF3KCkKKwkJZWxzZToKKwkJCVFkLkVyYXNlUmVjdChzZWxmLl9ib3VuZHMpCisJCisJZGVmIGRyYXcoc2VsZiwgdmlzUmduID0gTm9uZSk6CisJCWlmIHNlbGYuX3Zpc2libGU6CisJCQkjIGRyYXcgeW91ciBzdHVmZiBoZXJlCisJCQlwYXNzCisJCisJZGVmIGdldHBvc3NpemUoc2VsZik6CisJCXJldHVybiBzZWxmLl9wb3NzaXplCisJCisJZGVmIGdldGJvdW5kcyhzZWxmKToKKwkJcmV0dXJuIHNlbGYuX2JvdW5kcworCQorCWRlZiBtb3ZlKHNlbGYsIHgsIHkgPSBOb25lKToKKwkJIiIiYWJzb2x1dGUgbW92ZSIiIgorCQlpZiB5ID09IE5vbmU6CisJCQl4LCB5ID0geAorCQlpZiB0eXBlKHNlbGYuX3Bvc3NpemUpIDw+IFR1cGxlVHlwZToKKwkJCXJhaXNlIFdpZGdldHNFcnJvciwgImNhbid0IG1vdmUgd2lkZ2V0IHdpdGggYm91bmRzIGZ1bmN0aW9uIgorCQlsLCB0LCByLCBiID0gc2VsZi5fcG9zc2l6ZQorCQlzZWxmLnJlc2l6ZSh4LCB5LCByLCBiKQorCQorCWRlZiBybW92ZShzZWxmLCB4LCB5ID0gTm9uZSk6CisJCSIiInJlbGF0aXZlIG1vdmUiIiIKKwkJaWYgeSA9PSBOb25lOgorCQkJeCwgeSA9IHgKKwkJaWYgdHlwZShzZWxmLl9wb3NzaXplKSA8PiBUdXBsZVR5cGU6CisJCQlyYWlzZSBXaWRnZXRzRXJyb3IsICJjYW4ndCBtb3ZlIHdpZGdldCB3aXRoIGJvdW5kcyBmdW5jdGlvbiIKKwkJbCwgdCwgciwgYiA9IHNlbGYuX3Bvc3NpemUKKwkJc2VsZi5yZXNpemUobCArIHgsIHQgKyB5LCByLCBiKQorCQkKKwlkZWYgcmVzaXplKHNlbGYsICphcmdzKToKKwkJI3ByaW50ICJ5ZXAuIiwgYXJncworCQlpZiBsZW4oYXJncykgPT0gMToKKwkJCWlmIHR5cGUoYXJnc1swXSkgPT0gRnVuY3Rpb25UeXBlIG9yIHR5cGUoYXJnc1swXSkgPT0gTWV0aG9kVHlwZToKKwkJCQlzZWxmLl9wb3NzaXplID0gYXJnc1swXQorCQkJZWxzZToKKwkJCQlhcHBseShzZWxmLnJlc2l6ZSwgYXJnc1swXSkKKwkJZWxpZiBsZW4oYXJncykgPT0gMjoKKwkJCXNlbGYuX3Bvc3NpemUgPSAoMCwgMCkgKyBhcmdzCisJCWVsaWYgbGVuKGFyZ3MpID09IDQ6CisJCQlzZWxmLl9wb3NzaXplID0gYXJncworCQllbHNlOgorCQkJcmFpc2UgVHlwZUVycm9yLCAid3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50cyIKKwkJc2VsZi5fY2FsY2JvdW5kcygpCisJCisJZGVmIG9wZW4oc2VsZik6CisJCXNlbGYuX2NhbGNib3VuZHMoKQorCQorCWRlZiBjbG9zZShzZWxmKToKKwkJI3ByaW50ICJ4eHggQ2xvc2luZyBXaWRnZXQiCisJCWRlbCBzZWxmLl9jYWxsYmFjaworCQlkZWwgc2VsZi5fcG9zc2l6ZQorCQlkZWwgc2VsZi5fYmluZGluZ3MKKwkJZGVsIHNlbGYuX3BhcmVudAorCQlkZWwgc2VsZi5fcGFyZW50d2luZG93CisJCisJZGVmIGJpbmQoc2VsZiwga2V5LCBjYWxsYmFjayk6CisJCSIiImJpbmQgYSBrZXkgb3IgYW4gJ2V2ZW50JyB0byBhIGNhbGxiYWNrIiIiCisJCWlmIGNhbGxiYWNrOgorCQkJc2VsZi5fYmluZGluZ3Nba2V5XSA9IGNhbGxiYWNrCisJCWVsaWYgc2VsZi5fYmluZGluZ3MuaGFzX2tleShrZXkpOgorCQkJZGVsIHNlbGYuX2JpbmRpbmdzW2tleV0KKwkKKwlkZWYgYWRqdXN0KHNlbGYsIG9sZGJvdW5kcyk6CisJCXNlbGYuU2V0UG9ydCgpCisJCVdpbi5JbnZhbFJlY3Qob2xkYm91bmRzKQorCQlXaW4uSW52YWxSZWN0KHNlbGYuX2JvdW5kcykKKwkKKwlkZWYgX2NhbGNib3VuZHMoc2VsZik6CisJCW9sZGJvdW5kcyA9IHNlbGYuX2JvdW5kcworCQlwbCwgcHQsIHByLCBwYiA9IHNlbGYuX3BhcmVudC5fYm91bmRzCisJCWlmIGNhbGxhYmxlKHNlbGYuX3Bvc3NpemUpOgorCQkJd2lkdGggPSBwciAtIHBsCisJCQloZWlnaHQgPSBwYiAtIHB0CisJCQlzZWxmLl9ib3VuZHMgPSBRZC5PZmZzZXRSZWN0KHNlbGYuX3Bvc3NpemUod2lkdGgsIGhlaWdodCksIHBsLCBwdCkKKwkJZWxzZToKKwkJCWwsIHQsIHIsIGIgPSBzZWxmLl9wb3NzaXplCisJCQlpZiBsIDwgLTE6CisJCQkJbCA9IHByICsgbAorCQkJZWxzZToKKwkJCQlsID0gcGwgKyBsCisJCQlpZiB0IDwgLTE6CisJCQkJdCA9IHBiICsgdAorCQkJZWxzZToKKwkJCQl0ID0gcHQgKyB0CisJCQlpZiByID4gMToKKwkJCQlyID0gbCArIHIKKwkJCWVsc2U6CisJCQkJciA9IHByICsgcgorCQkJaWYgYiA+IDE6CisJCQkJYiA9IHQgKyBiCisJCQllbHNlOgorCQkJCWIgPSBwYiArIGIKKwkJCXNlbGYuX2JvdW5kcyA9IChsLCB0LCByLCBiKQorCQlpZiBvbGRib3VuZHMgYW5kIG9sZGJvdW5kcyA8PiBzZWxmLl9ib3VuZHM6CisJCQlzZWxmLmFkanVzdChvbGRib3VuZHMpCisJCWZvciB3IGluIHNlbGYuX3dpZGdldHM6CisJCQl3Ll9jYWxjYm91bmRzKCkKKwkKKwlkZWYgdGVzdChzZWxmLCBwb2ludCk6CisJCWlmIFFkLlB0SW5SZWN0KHBvaW50LCBzZWxmLl9ib3VuZHMpOgorCQkJcmV0dXJuIDEKKwkKKwlkZWYgY2xpY2soc2VsZiwgcG9pbnQsIG1vZGlmaWVycyk6CisJCXBhc3MKKwkKKwlkZWYgZmluZHdpZGdldChzZWxmLCBwb2ludCwgb25seWVuYWJsZWQgPSAxKToKKwkJaWYgc2VsZi50ZXN0KHBvaW50KToKKwkJCWZvciB3IGluIHNlbGYuX3dpZGdldHM6CisJCQkJd2lkZ2V0ID0gdy5maW5kd2lkZ2V0KHBvaW50KQorCQkJCWlmIHdpZGdldCBpcyBub3QgTm9uZToKKwkJCQkJcmV0dXJuIHdpZGdldAorCQkJaWYgc2VsZi5fZW5hYmxlZCBvciBub3Qgb25seWVuYWJsZWQ6CisJCQkJcmV0dXJuIHNlbGYKKwkKKwlkZWYgZm9yYWxsKHNlbGYsIG1ldGhvZG5hbWUsICphcmdzKToKKwkJZm9yIHcgaW4gc2VsZi5fd2lkZ2V0czoKKwkJCXJ2ID0gYXBwbHkody5mb3JhbGwsIChtZXRob2RuYW1lLCkgKyBhcmdzKQorCQkJaWYgcnY6IAorCQkJCXJldHVybiBydgorCQlpZiBzZWxmLl9iaW5kaW5ncy5oYXNfa2V5KCI8IiArIG1ldGhvZG5hbWUgKyAiPiIpOgorCQkJY2FsbGJhY2sgPSBzZWxmLl9iaW5kaW5nc1siPCIgKyBtZXRob2RuYW1lICsgIj4iXQorCQkJcnYgPSBhcHBseShjYWxsYmFjaywgYXJncykKKwkJCWlmIHJ2OiAKKwkJCQlyZXR1cm4gcnYKKwkJaWYgaGFzYXR0cihzZWxmLCBtZXRob2RuYW1lKToKKwkJCW1ldGhvZCA9IGdldGF0dHIoc2VsZiwgbWV0aG9kbmFtZSkKKwkJCXJldHVybiBhcHBseShtZXRob2QsIGFyZ3MpCisJCisJZGVmIGZvcmFsbF9idXRzZWxmKHNlbGYsIG1ldGhvZG5hbWUsICphcmdzKToKKwkJZm9yIHcgaW4gc2VsZi5fd2lkZ2V0czoKKwkJCXJ2ID0gYXBwbHkody5mb3JhbGwsIChtZXRob2RuYW1lLCkgKyBhcmdzKQorCQkJaWYgcnY6IAorCQkJCXJldHVybiBydgorCQorCWRlZiBmb3JhbGxfZnJvbWJvdHRvbShzZWxmLCBtZXRob2RuYW1lLCAqYXJncyk6CisJCWlmIHNlbGYuX2JpbmRpbmdzLmhhc19rZXkoIjwiICsgbWV0aG9kbmFtZSArICI+Iik6CisJCQljYWxsYmFjayA9IHNlbGYuX2JpbmRpbmdzWyI8IiArIG1ldGhvZG5hbWUgKyAiPiJdCisJCQlydiA9IGFwcGx5KGNhbGxiYWNrLCBhcmdzKQorCQkJaWYgcnY6IAorCQkJCXJldHVybiBydgorCQlpZiBoYXNhdHRyKHNlbGYsIG1ldGhvZG5hbWUpOgorCQkJbWV0aG9kID0gZ2V0YXR0cihzZWxmLCBtZXRob2RuYW1lKQorCQkJcnYgPSBhcHBseShtZXRob2QsIGFyZ3MpCisJCQlpZiBydjogCisJCQkJcmV0dXJuIHJ2CisJCWZvciB3IGluIHNlbGYuX3dpZGdldHM6CisJCQlydiA9IGFwcGx5KHcuZm9yYWxsX2Zyb21ib3R0b20sIChtZXRob2RuYW1lLCkgKyBhcmdzKQorCQkJaWYgcnY6IAorCQkJCXJldHVybiBydgorCQorCWRlZiBfYWRkd2lkZ2V0KHNlbGYsIGtleSwgd2lkZ2V0KToKKwkJaWYgd2lkZ2V0IGluIHNlbGYuX3dpZGdldHM6CisJCQlyYWlzZSBWYWx1ZUVycm9yLCAiZHVwbGljYXRlIHdpZGdldCIKKwkJaWYgc2VsZi5fd2lkZ2V0c2RpY3QuaGFzX2tleShrZXkpOgorCQkJc2VsZi5fcmVtb3Zld2lkZ2V0KGtleSkKKwkJc2VsZi5fd2lkZ2V0cy5hcHBlbmQod2lkZ2V0KQorCQlzZWxmLl93aWRnZXRzZGljdFtrZXldID0gd2lkZ2V0CisJCXdpZGdldC5fcGFyZW50ID0gc2VsZgorCQlzZWxmLl9zZXRwYXJlbnR3aW5kb3cod2lkZ2V0KQorCQlpZiBzZWxmLl9wYXJlbnR3aW5kb3cgYW5kIHNlbGYuX3BhcmVudHdpbmRvdy53aWQ6CisJCQl3aWRnZXQuZm9yYWxsX2Zyb21ib3R0b20oIm9wZW4iKQorCQkJV2luLkludmFsUmVjdCh3aWRnZXQuX2JvdW5kcykKKwkKKwlkZWYgX3NldHBhcmVudHdpbmRvdyhzZWxmLCB3aWRnZXQpOgorCQl3aWRnZXQuX3BhcmVudHdpbmRvdyA9IHNlbGYuX3BhcmVudHdpbmRvdworCQlmb3IgdyBpbiB3aWRnZXQuX3dpZGdldHM6CisJCQlzZWxmLl9zZXRwYXJlbnR3aW5kb3codykKKwkKKwlkZWYgX3JlbW92ZXdpZGdldChzZWxmLCBrZXkpOgorCQlpZiBub3Qgc2VsZi5fd2lkZ2V0c2RpY3QuaGFzX2tleShrZXkpOgorCQkJcmFpc2UgS2V5RXJyb3IsICJubyB3aWRnZXQgd2l0aCBrZXkgIiArIGBrZXlgCisJCXdpZGdldCA9IHNlbGYuX3dpZGdldHNkaWN0W2tleV0KKwkJZm9yIGsgaW4gd2lkZ2V0Ll93aWRnZXRzZGljdC5rZXlzKCk6CisJCQl3aWRnZXQuX3JlbW92ZXdpZGdldChrKQorCQlpZiBzZWxmLl9wYXJlbnR3aW5kb3cuX2N1cnJlbnR3aWRnZXQgPT0gd2lkZ2V0OgorCQkJd2lkZ2V0LnNlbGVjdCgwKQorCQkJc2VsZi5fcGFyZW50d2luZG93Ll9jdXJyZW50d2lkZ2V0ID0gTm9uZQorCQlzZWxmLlNldFBvcnQoKQorCQlXaW4uSW52YWxSZWN0KHdpZGdldC5fYm91bmRzKQorCQl3aWRnZXQuY2xvc2UoKQorCQlkZWwgc2VsZi5fd2lkZ2V0c2RpY3Rba2V5XQorCQlzZWxmLl93aWRnZXRzLnJlbW92ZSh3aWRnZXQpCisJCisJZGVmIF9fc2V0YXR0cl9fKHNlbGYsIGF0dHIsIHZhbHVlKToKKwkJaWYgdHlwZSh2YWx1ZSkgPT0gSW5zdGFuY2VUeXBlIGFuZCBIYXNCYXNlQ2xhc3ModmFsdWUsIFdpZGdldCkgYW5kCVwKKwkJCQlhdHRyIG5vdCBpbiAoIl9jdXJyZW50d2lkZ2V0IiwgIl9sYXN0cm9sbG92ZXIiLCAKKwkJCQkJIl9wYXJlbnQiLCAiX3BhcmVudHdpbmRvdyIsICJfZGVmYXVsdGJ1dHRvbiIpOgorCQkJaWYgaGFzYXR0cihzZWxmLCBhdHRyKToKKwkJCQlyYWlzZSBWYWx1ZUVycm9yLCAiQ2FuJ3QgcmVwbGFjZSBleGlzdGluZyBhdHRyaWJ1dGU6ICIgKyBhdHRyCisJCQlzZWxmLl9hZGR3aWRnZXQoYXR0ciwgdmFsdWUpCisJCXNlbGYuX19kaWN0X19bYXR0cl0gPSB2YWx1ZQorCQorCWRlZiBfX2RlbGF0dHJfXyhzZWxmLCBhdHRyKToKKwkJaWYgYXR0ciA9PSAiX3dpZGdldHNkaWN0IjoKKwkJCXJhaXNlIEF0dHJpYnV0ZUVycm9yLCAiY2Fubm90IGRlbGV0ZSBhdHRyaWJ1dGUgX3dpZGdldHNkaWN0IgorCQlpZiBzZWxmLl93aWRnZXRzZGljdC5oYXNfa2V5KGF0dHIpOgorCQkJc2VsZi5fcmVtb3Zld2lkZ2V0KGF0dHIpCisJCQlpZiBzZWxmLl9fZGljdF9fLmhhc19rZXkoYXR0cik6CisJCQkJZGVsIHNlbGYuX19kaWN0X19bYXR0cl0KKwkJZWxpZiBzZWxmLl9fZGljdF9fLmhhc19rZXkoYXR0cik6CisJCQlkZWwgc2VsZi5fX2RpY3RfX1thdHRyXQorCQllbHNlOgorCQkJcmFpc2UgQXR0cmlidXRlRXJyb3IsIGF0dHIKKwkKKwlkZWYgX19zZXRpdGVtX18oc2VsZiwga2V5LCB2YWx1ZSk6CisJCXNlbGYuX2FkZHdpZGdldChrZXksIHZhbHVlKQorCQorCWRlZiBfX2dldGl0ZW1fXyhzZWxmLCBrZXkpOgorCQlpZiBub3Qgc2VsZi5fd2lkZ2V0c2RpY3QuaGFzX2tleShrZXkpOgorCQkJcmFpc2UgS2V5RXJyb3IsIGtleQorCQlyZXR1cm4gc2VsZi5fd2lkZ2V0c2RpY3Rba2V5XQorCQorCWRlZiBfX2RlbGl0ZW1fXyhzZWxmLCBrZXkpOgorCQlzZWxmLl9yZW1vdmV3aWRnZXQoa2V5KQorCQorCWRlZiBTZXRQb3J0KHNlbGYpOgorCQlzZWxmLl9wYXJlbnR3aW5kb3cuU2V0UG9ydCgpCisJCisJZGVmIF9fZGVsX18oc2VsZik6CisJCWlmIERFQlVHOgorCQkJcHJpbnQgIiVzIGluc3RhbmNlIGRlbGV0ZWQiICUgc2VsZi5fX2NsYXNzX18uX19uYW1lX18KKwkKKwlkZWYgX2RyYXdib3VuZHMoc2VsZik6CisJCVFkLkZyYW1lUmVjdChzZWxmLl9ib3VuZHMpCisKKworY2xhc3MgQ2xpY2thYmxlV2lkZ2V0KFdpZGdldCk6CisKKwlkZWYgY2xpY2soc2VsZiwgcG9pbnQsIG1vZGlmaWVycyk6CisJCXBhc3MKKwkKKwlkZWYgZW5hYmxlKHNlbGYsIG9ub2ZmKToKKwkJc2VsZi5fZW5hYmxlZCA9IG9ub2ZmCisJCXNlbGYuU2V0UG9ydCgpCisJCXNlbGYuZHJhdygpCisJCisJZGVmIGNhbGxiYWNrKHNlbGYpOgorCQlpZiBzZWxmLl9jYWxsYmFjazoKKwkJCXJldHVybiBDYWxsYmFja0NhbGwoc2VsZi5fY2FsbGJhY2ssIDEpCisJCisKK2NsYXNzIFNlbGVjdGFibGVXaWRnZXQoQ2xpY2thYmxlV2lkZ2V0KToKKworCV9zZWxlY3RhYmxlID0gMQorCQorCWRlZiBzZWxlY3Qoc2VsZiwgb25vZmYsIGlzY2xpY2sgPSAwKToKKwkJaWYgb25vZmYgPT0gc2VsZi5fc2VsZWN0ZWQ6CisJCQlyZXR1cm4gMQorCQlpZiBzZWxmLl9iaW5kaW5ncy5oYXNfa2V5KCI8c2VsZWN0PiIpOgorCQkJY2FsbGJhY2sgPSBzZWxmLl9iaW5kaW5nc1siPHNlbGVjdD4iXQorCQkJaWYgY2FsbGJhY2sob25vZmYpOgorCQkJCXJldHVybiAxCisJCXNlbGYuX3NlbGVjdGVkID0gb25vZmYKKwkJaWYgb25vZmY6CisJCQlpZiBzZWxmLl9wYXJlbnR3aW5kb3cuX2N1cnJlbnR3aWRnZXQgaXMgbm90IE5vbmU6CisJCQkJc2VsZi5fcGFyZW50d2luZG93Ll9jdXJyZW50d2lkZ2V0LnNlbGVjdCgwKQorCQkJc2VsZi5fcGFyZW50d2luZG93Ll9jdXJyZW50d2lkZ2V0ID0gc2VsZgorCQllbHNlOgorCQkJc2VsZi5fcGFyZW50d2luZG93Ll9jdXJyZW50d2lkZ2V0ID0gTm9uZQorCQorCWRlZiBrZXkoc2VsZiwgY2hhciwgZXZlbnQpOgorCQlwYXNzCisJCisJZGVmIGRyYXdzZWxmcmFtZShzZWxmLCBvbm9mZik6CisJCWlmIG5vdCBzZWxmLl9wYXJlbnR3aW5kb3cuX2hhc3NlbGZyYW1lczoKKwkJCXJldHVybgorCQl0aGlja3JlY3QgPSBRZC5JbnNldFJlY3Qoc2VsZi5fYm91bmRzLCAtMywgLTMpCisJCXN0YXRlID0gUWQuR2V0UGVuU3RhdGUoKQorCQlRZC5QZW5TaXplKDIsIDIpCisJCWlmIG9ub2ZmOgorCQkJUWQuUGVuUGF0KFFkLnFkLmJsYWNrKQorCQllbHNlOgorCQkJUWQuUGVuUGF0KFFkLnFkLndoaXRlKQorCQlRZC5GcmFtZVJlY3QodGhpY2tyZWN0KQorCQlRZC5TZXRQZW5TdGF0ZShzdGF0ZSkKKwkKKwlkZWYgYWRqdXN0KHNlbGYsIG9sZGJvdW5kcyk6CisJCXNlbGYuU2V0UG9ydCgpCisJCWlmIHNlbGYuX3NlbGVjdGVkOgorCQkJV2luLkludmFsUmVjdChRZC5JbnNldFJlY3Qob2xkYm91bmRzLCAtMywgLTMpKQorCQkJV2luLkludmFsUmVjdChRZC5JbnNldFJlY3Qoc2VsZi5fYm91bmRzLCAtMywgLTMpKQorCQllbHNlOgorCQkJV2luLkludmFsUmVjdChvbGRib3VuZHMpCisJCQlXaW4uSW52YWxSZWN0KHNlbGYuX2JvdW5kcykKKworCitjbGFzcyBfTGluZShXaWRnZXQpOgorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBwb3NzaXplLCB0aGlja25lc3MgPSAxKToKKwkJV2lkZ2V0Ll9faW5pdF9fKHNlbGYsIHBvc3NpemUpCisJCXNlbGYuX3RoaWNrbmVzcyA9IHRoaWNrbmVzcworCQorCWRlZiBvcGVuKHNlbGYpOgorCQlzZWxmLl9jYWxjYm91bmRzKCkKKwkJc2VsZi5TZXRQb3J0KCkKKwkJc2VsZi5kcmF3KCkKKwkKKwlkZWYgZHJhdyhzZWxmLCB2aXNSZ24gPSBOb25lKToKKwkJaWYgc2VsZi5fdmlzaWJsZToKKwkJCVFkLlBhaW50UmVjdChzZWxmLl9ib3VuZHMpCisJCisJZGVmIF9kcmF3Ym91bmRzKHNlbGYpOgorCQlwYXNzCisKK2NsYXNzIEhvcml6b250YWxMaW5lKF9MaW5lKToKKwkKKwlkZWYgX2NhbGNib3VuZHMoc2VsZik6CisJCVdpZGdldC5fY2FsY2JvdW5kcyhzZWxmKQorCQlsLCB0LCByLCBiID0gc2VsZi5fYm91bmRzCisJCXNlbGYuX2JvdW5kcyA9IGwsIHQsIHIsIHQgKyBzZWxmLl90aGlja25lc3MKKworY2xhc3MgVmVydGljYWxMaW5lKF9MaW5lKToKKwkKKwlkZWYgX2NhbGNib3VuZHMoc2VsZik6CisJCVdpZGdldC5fY2FsY2JvdW5kcyhzZWxmKQorCQlsLCB0LCByLCBiID0gc2VsZi5fYm91bmRzCisJCXNlbGYuX2JvdW5kcyA9IGwsIHQsIGwgKyBzZWxmLl90aGlja25lc3MsIGIKKworCitjbGFzcyBGcmFtZShXaWRnZXQpOgorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBwb3NzaXplLCBwYXR0ZXJuID0gUWQucWQuYmxhY2ssIGNvbG9yID0gKDAsIDAsIDApKToKKwkJV2lkZ2V0Ll9faW5pdF9fKHNlbGYsIHBvc3NpemUpCisJCXNlbGYuX2ZyYW1lcGF0dGVybiA9IHBhdHRlcm4KKwkJc2VsZi5fZnJhbWVjb2xvciA9IGNvbG9yCisJCisJZGVmIHNldGNvbG9yKHNlbGYsIGNvbG9yKToKKwkJc2VsZi5fZnJhbWVjb2xvciA9IGNvbG9yCisJCXNlbGYuZHJhdygpCisJCisJZGVmIHNldHBhdHRlcm4oc2VsZiwgcGF0dGVybik6CisJCXNlbGYuX2ZyYW1lcGF0dGVybiA9IHBhdHRlcm4KKwkJc2VsZi5kcmF3KCkKKwkJCisJZGVmIGRyYXcoc2VsZiwgdmlzUmduID0gTm9uZSk6CisJCWlmIHNlbGYuX3Zpc2libGU6CisJCQlwZW5zdGF0ZSA9IFFkLkdldFBlblN0YXRlKCkKKwkJCVFkLlBlblBhdChzZWxmLl9mcmFtZXBhdHRlcm4pCisJCQlRZC5SR0JGb3JlQ29sb3Ioc2VsZi5fZnJhbWVjb2xvcikKKwkJCVFkLkZyYW1lUmVjdChzZWxmLl9ib3VuZHMpCisJCQlRZC5SR0JGb3JlQ29sb3IoKDAsIDAsIDApKQorCQkJUWQuU2V0UGVuU3RhdGUocGVuc3RhdGUpCisKKworY2xhc3MgR3JvdXAoV2lkZ2V0KTogcGFzcworCQorCitjbGFzcyBIb3Jpem9udGFsUGFuZXMoV2lkZ2V0KToKKwkKKwlfZGlyZWN0aW9uID0gMQorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBwb3NzaXplLCBwYW5lc2l6ZXMgPSBOb25lLCBndXR0ZXIgPSA4KToKKwkJQ2xpY2thYmxlV2lkZ2V0Ll9faW5pdF9fKHNlbGYsIHBvc3NpemUpCisJCXNlbGYuX3BhbmVzaXplcyA9IHBhbmVzaXplcworCQlzZWxmLl9ndXR0ZXIgPSBndXR0ZXIKKwkJc2VsZi5fZW5hYmxlZCA9IDEKKwkJc2VsZi5zZXR1cHBhbmVzKCkKKwkKKwlkZWYgb3BlbihzZWxmKToKKwkJc2VsZi5pbnN0YWxsYm91bmRzKCkKKwkJQ2xpY2thYmxlV2lkZ2V0Lm9wZW4oc2VsZikKKwkKKwlkZWYgc2V0dXBwYW5lcyhzZWxmKToKKwkJcGFuZXNpemVzID0gc2VsZi5fcGFuZXNpemVzCisJCXRvdGFsID0gMAorCQlpZiBwYW5lc2l6ZXMgaXMgbm90IE5vbmU6CisJCQkjaWYgbGVuKHNlbGYuX3dpZGdldHMpIDw+IGxlbihwYW5lc2l6ZXMpOgorCQkJIwlyYWlzZSBUeXBlRXJyb3IsICdudW1iZXIgb2Ygd2lkZ2V0cyBkb2VzIG5vdCBtYXRjaCBudW1iZXIgb2YgcGFuZXMnCisJCQlmb3IgcGFuZXNpemUgaW4gcGFuZXNpemVzOgorCQkJCWlmIG5vdCAwIDwgcGFuZXNpemUgPCAxOgorCQkJCQlyYWlzZSBUeXBlRXJyb3IsICdwYW5lIHNpemVzIG11c3QgYmUgYmV0d2VlbiAwIGFuZCAxLCBub3QgaW5jbHVkaW5nLicKKwkJCQl0b3RhbCA9IHRvdGFsICsgcGFuZXNpemUKKwkJCWlmIHJvdW5kKHRvdGFsLCA0KSA8PiAxLjA6CisJCQkJcmFpc2UgVHlwZUVycm9yLCAncGFuZSBzaXplcyBtdXN0IGFkZCB1cCB0byAxJworCQllbHNlOgorCQkJc3RlcCA9IDEuMCAvIGxlbihzZWxmLl93aWRnZXRzKQorCQkJcGFuZXNpemVzID0gW10KKwkJCWZvciBpIGluIHJhbmdlKGxlbihzZWxmLl93aWRnZXRzKSk6CisJCQkJcGFuZXNpemVzLmFwcGVuZChzdGVwKQorCQljdXJyZW50ID0gMAorCQlzZWxmLl9wYW5lc2l6ZXMgPSBbXQorCQlzZWxmLl9ndXR0ZXJzID0gW10KKwkJZm9yIHBhbmVzaXplIGluIHBhbmVzaXplczoKKwkJCWlmIGN1cnJlbnQ6CisJCQkJc2VsZi5fZ3V0dGVycy5hcHBlbmQoY3VycmVudCkKKwkJCXNlbGYuX3BhbmVzaXplcy5hcHBlbmQoY3VycmVudCwgY3VycmVudCArIHBhbmVzaXplKQorCQkJY3VycmVudCA9IGN1cnJlbnQgKyBwYW5lc2l6ZQorCQlzZWxmLm1ha2VwYW5lYm91bmRzKCkKKwkKKwlkZWYgZ2V0cGFuZXNpemVzKHNlbGYpOgorCQlyZXR1cm4gbWFwKGxhbWJkYSAoZnIsIHRvKTogdG8tZnIsICBzZWxmLl9wYW5lc2l6ZXMpCisJCisJYm91bmRzdGVtcGxhdGUgPSAibGFtYmRhIHdpZHRoLCBoZWlnaHQ6ICgwLCBoZWlnaHQgKiAlcyArICVkLCB3aWR0aCwgaGVpZ2h0ICogJXMgKyAlZCkiCisJCisJZGVmIG1ha2VwYW5lYm91bmRzKHNlbGYpOgorCQloYWxmZ3V0dGVyID0gc2VsZi5fZ3V0dGVyIC8gMgorCQlzZWxmLl9wYW5lYm91bmRzID0gW10KKwkJZm9yIGkgaW4gcmFuZ2UobGVuKHNlbGYuX3BhbmVzaXplcykpOgorCQkJcGFuZXN0YXJ0LCBwYW5lZW5kID0gc2VsZi5fcGFuZXNpemVzW2ldCisJCQlib3VuZHNzdHJpbmcgPSBzZWxmLmJvdW5kc3RlbXBsYXRlICUgKGBwYW5lc3RhcnRgLCBwYW5lc3RhcnQgYW5kIGhhbGZndXR0ZXIsIAorCQkJCQkJCWBwYW5lZW5kYCwgKHBhbmVlbmQgPD4gMS4wKSBhbmQgLWhhbGZndXR0ZXIpCisJCQlzZWxmLl9wYW5lYm91bmRzLmFwcGVuZChldmFsKGJvdW5kc3N0cmluZykpCisJCisJZGVmIGluc3RhbGxib3VuZHMoc2VsZik6CisJCSNzZWxmLnNldHVwcGFuZXMoKQorCQlmb3IgaSBpbiByYW5nZShsZW4oc2VsZi5fd2lkZ2V0cykpOgorCQkJdyA9IHNlbGYuX3dpZGdldHNbaV0KKwkJCXcuX3Bvc3NpemUgPSBzZWxmLl9wYW5lYm91bmRzW2ldCisJCQkjaWYgaGFzYXR0cih3LCAic2V0dXBwYW5lcyIpOgorCQkJIwl3LnNldHVwcGFuZXMoKQorCQkJaWYgaGFzYXR0cih3LCAiaW5zdGFsbGJvdW5kcyIpOgorCQkJCXcuaW5zdGFsbGJvdW5kcygpCisJCisJZGVmIHJvbGxvdmVyKHNlbGYsIHBvaW50LCBvbm9mZik6CisJCWlmIG9ub2ZmOgorCQkJb3JnbW91c2UgPSBwb2ludFtzZWxmLl9kaXJlY3Rpb25dCisJCQloYWxmZ3V0dGVyID0gc2VsZi5fZ3V0dGVyIC8gMgorCQkJbCwgdCwgciwgYiA9IHNlbGYuX2JvdW5kcworCQkJaWYgc2VsZi5fZGlyZWN0aW9uOgorCQkJCWJlZ2luLCBlbmQgPSB0LCBiCisJCQllbHNlOgorCQkJCWJlZ2luLCBlbmQgPSBsLCByCisJCQkKKwkJCWkgPSBzZWxmLmZpbmRndXR0ZXIob3JnbW91c2UsIGJlZ2luLCBlbmQpCisJCQlpZiBpIGlzIE5vbmU6CisJCQkJU2V0Q3Vyc29yKCJhcnJvdyIpCisJCQllbHNlOgorCQkJCVNldEN1cnNvcihzZWxmLl9kaXJlY3Rpb24gYW5kICd2bW92ZXInIG9yICdobW92ZXInKQorCQorCWRlZiBmaW5kZ3V0dGVyKHNlbGYsIG9yZ21vdXNlLCBiZWdpbiwgZW5kKToKKwkJdG9sZXJhbmNlID0gbWF4KDQsIHNlbGYuX2d1dHRlcikgLyAyCisJCWZvciBpIGluIHJhbmdlKGxlbihzZWxmLl9ndXR0ZXJzKSk6CisJCQlwb3MgPSBiZWdpbiArIChlbmQgLSBiZWdpbikgKiBzZWxmLl9ndXR0ZXJzW2ldCisJCQlpZiBhYnMob3JnbW91c2UgLSBwb3MpIDw9IHRvbGVyYW5jZToKKwkJCQlicmVhaworCQllbHNlOgorCQkJcmV0dXJuCisJCXJldHVybiBpCisJCisJZGVmIGNsaWNrKHNlbGYsIHBvaW50LCBtb2RpZmllcnMpOgorCQkjIHdoYXQgYSBtZXNzLi4uCisJCW9yZ21vdXNlID0gcG9pbnRbc2VsZi5fZGlyZWN0aW9uXQorCQloYWxmZ3V0dGVyID0gc2VsZi5fZ3V0dGVyIC8gMgorCQlsLCB0LCByLCBiID0gc2VsZi5fYm91bmRzCisJCWlmIHNlbGYuX2RpcmVjdGlvbjoKKwkJCWJlZ2luLCBlbmQgPSB0LCBiCisJCWVsc2U6CisJCQliZWdpbiwgZW5kID0gbCwgcgorCQkKKwkJaSA9IHNlbGYuZmluZGd1dHRlcihvcmdtb3VzZSwgYmVnaW4sIGVuZCkKKwkJaWYgaSBpcyBOb25lOgorCQkJcmV0dXJuCisJCQorCQlwb3MgPSBvcmdwb3MgPSBiZWdpbiArIChlbmQgLSBiZWdpbikgKiBzZWxmLl9ndXR0ZXJzW2ldCSMgaW5pdCBwb3MgdG9vLCBmb3IgZmFzdCBjbGljayBvbiBib3JkZXIsIGJ1ZyBkb25lIGJ5IFBldHIKKwkJCisJCW1pbnBvcyA9IHNlbGYuX3BhbmVzaXplc1tpXVswXQorCQltYXhwb3MgPSBzZWxmLl9wYW5lc2l6ZXNbaSsxXVsxXQorCQltaW5wb3MgPSBiZWdpbiArIChlbmQgLSBiZWdpbikgKiBtaW5wb3MgKyA2NAorCQltYXhwb3MgPSBiZWdpbiArIChlbmQgLSBiZWdpbikgKiBtYXhwb3MgLSA2NAorCQlpZiBtaW5wb3MgPiBvcmdwb3MgYW5kIG1heHBvcyA8IG9yZ3BvczoKKwkJCXJldHVybgorCQkKKwkJI1NldEN1cnNvcigiZmlzdCIpCisJCXNlbGYuU2V0UG9ydCgpCisJCWlmIHNlbGYuX2RpcmVjdGlvbjoKKwkJCXJlY3QgPSBsLCBvcmdwb3MgLSAxLCByLCBvcmdwb3MKKwkJZWxzZToKKwkJCXJlY3QgPSBvcmdwb3MgLSAxLCB0LCBvcmdwb3MsIGIKKwkJCisJCSMgdHJhY2sgbW91c2UgLS0tIFhYWCAgbW92ZSB0byBzZXBhcmF0ZSBtZXRob2Q/CisJCVFkLlBlbk1vZGUoUXVpY2tEcmF3LnNyY1hvcikKKwkJUWQuUGVuUGF0KFFkLnFkLmdyYXkpCisJCVFkLlBhaW50UmVjdChyZWN0KQorCQlsYXN0cG9zID0gTm9uZQorCQl3aGlsZSBFdnQuQnV0dG9uKCk6CisJCQlwb3MgPSBvcmdwb3MgLSBvcmdtb3VzZSArIEV2dC5HZXRNb3VzZSgpW3NlbGYuX2RpcmVjdGlvbl0KKwkJCXBvcyA9IG1heChwb3MsIG1pbnBvcykKKwkJCXBvcyA9IG1pbihwb3MsIG1heHBvcykKKwkJCWlmIHBvcyA9PSBsYXN0cG9zOgorCQkJCWNvbnRpbnVlCisJCQlRZC5QZW5QYXQoUWQucWQuZ3JheSkKKwkJCVFkLlBhaW50UmVjdChyZWN0KQorCQkJaWYgc2VsZi5fZGlyZWN0aW9uOgorCQkJCXJlY3QgPSBsLCBwb3MgLSAxLCByLCBwb3MKKwkJCWVsc2U6CisJCQkJcmVjdCA9IHBvcyAtIDEsIHQsIHBvcywgYgorCQkJUWQuUGVuUGF0KFFkLnFkLmdyYXkpCisJCQlRZC5QYWludFJlY3QocmVjdCkKKwkJCWxhc3Rwb3MgPSBwb3MKKwkJUWQuUGFpbnRSZWN0KHJlY3QpCisJCVFkLlBlbk5vcm1hbCgpCisJCVNldEN1cnNvcigid2F0Y2giKQorCQkKKwkJbmV3cG9zID0gKHBvcyAtIGJlZ2luKSAvIGZsb2F0KGVuZCAtIGJlZ2luKQorCQlzZWxmLl9ndXR0ZXJzW2ldID0gbmV3cG9zCisJCXNlbGYuX3BhbmVzaXplc1tpXSA9IHNlbGYuX3BhbmVzaXplc1tpXVswXSwgbmV3cG9zCisJCXNlbGYuX3BhbmVzaXplc1tpKzFdID0gbmV3cG9zLCBzZWxmLl9wYW5lc2l6ZXNbaSsxXVsxXQorCQlzZWxmLm1ha2VwYW5lYm91bmRzKCkKKwkJc2VsZi5pbnN0YWxsYm91bmRzKCkKKwkJc2VsZi5fY2FsY2JvdW5kcygpCisJCisKK2NsYXNzIFZlcnRpY2FsUGFuZXMoSG9yaXpvbnRhbFBhbmVzKToKKworCV9kaXJlY3Rpb24gPSAwCisJYm91bmRzdGVtcGxhdGUgPSAibGFtYmRhIHdpZHRoLCBoZWlnaHQ6ICh3aWR0aCAqICVzICsgJWQsIDAsIHdpZHRoICogJXMgKyAlZCwgaGVpZ2h0KSIKKworCisjIG1pc2MgdXRpbHMKKworZGVmIENhbGxiYWNrQ2FsbChjYWxsYmFjaywgbXVzdGZpdCwgKmFyZ3MpOgorCWlmIHR5cGUoY2FsbGJhY2spID09IEZ1bmN0aW9uVHlwZToKKwkJZnVuYyA9IGNhbGxiYWNrCisJCW1heGFyZ3MgPSBmdW5jLmZ1bmNfY29kZS5jb19hcmdjb3VudAorCWVsaWYgdHlwZShjYWxsYmFjaykgPT0gTWV0aG9kVHlwZToKKwkJZnVuYyA9IGNhbGxiYWNrLmltX2Z1bmMKKwkJbWF4YXJncyA9IGZ1bmMuZnVuY19jb2RlLmNvX2FyZ2NvdW50IC0gMQorCWVsc2U6CisJCWlmIGNhbGxhYmxlKGNhbGxiYWNrKToKKwkJCXJldHVybiBhcHBseShjYWxsYmFjaywgYXJncykKKwkJZWxzZToKKwkJCXJhaXNlIFR5cGVFcnJvciwgInVuY2FsbGFibGUgY2FsbGJhY2sgb2JqZWN0IgorCQorCWlmIGZ1bmMuZnVuY19kZWZhdWx0czoKKwkJbWluYXJncyA9IG1heGFyZ3MgLSBsZW4oZnVuYy5mdW5jX2RlZmF1bHRzKQorCWVsc2U6CisJCW1pbmFyZ3MgPSBtYXhhcmdzCisJaWYgbWluYXJncyA8PSBsZW4oYXJncykgPD0gbWF4YXJnczoKKwkJcmV0dXJuIGFwcGx5KGNhbGxiYWNrLCBhcmdzKQorCWVsaWYgbm90IG11c3RmaXQgYW5kIG1pbmFyZ3MgPT0gMDoKKwkJcmV0dXJuIGNhbGxiYWNrKCkKKwllbHNlOgorCQlpZiBtdXN0Zml0OgorCQkJcmFpc2UgVHlwZUVycm9yLCAiY2FsbGJhY2sgYWNjZXB0cyB3cm9uZyBudW1iZXIgb2YgYXJndW1lbnRzOiAiICsgYGxlbihhcmdzKWAKKwkJZWxzZToKKwkJCXJhaXNlIFR5cGVFcnJvciwgImNhbGxiYWNrIGFjY2VwdHMgd3JvbmcgbnVtYmVyIG9mIGFyZ3VtZW50czogMCBvciAiICsgYGxlbihhcmdzKWAKKworCitkZWYgSGFzQmFzZUNsYXNzKG9iaiwgY2xhc3NfKToKKwl0cnk6CisJCXJhaXNlIG9iagorCWV4Y2VwdCBjbGFzc186CisJCXJldHVybiAxCisJZXhjZXB0OgorCQlwYXNzCisJcmV0dXJuIDAKKworCitfY3Vyc29ycyA9IHsKKwkid2F0Y2giCTogUWQuR2V0Q3Vyc29yKFF1aWNrRHJhdy53YXRjaEN1cnNvcikuZGF0YSwKKwkiYXJyb3ciCTogUWQucWQuYXJyb3csCisJImlCZWFtIgk6IFFkLkdldEN1cnNvcihRdWlja0RyYXcuaUJlYW1DdXJzb3IpLmRhdGEsCisJImNyb3NzIgk6IFFkLkdldEN1cnNvcihRdWlja0RyYXcuY3Jvc3NDdXJzb3IpLmRhdGEsCisJInBsdXMiCQk6IFFkLkdldEN1cnNvcihRdWlja0RyYXcucGx1c0N1cnNvcikuZGF0YSwKKwkiaGFuZCIJOiBRZC5HZXRDdXJzb3IoNDY4KS5kYXRhLAorCSJmaXN0IgkJOiBRZC5HZXRDdXJzb3IoNDY5KS5kYXRhLAorCSJobW92ZXIiCTogUWQuR2V0Q3Vyc29yKDQ3MCkuZGF0YSwKKwkidm1vdmVyIgk6IFFkLkdldEN1cnNvcig0NzEpLmRhdGEKK30KKworZGVmIFNldEN1cnNvcih3aGF0KToKKwlRZC5TZXRDdXJzb3IoX2N1cnNvcnNbd2hhdF0pCmRpZmYgLS1naXQgYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvV2NvbnRyb2xzLnB5IGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1djb250cm9scy5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi44YzNjMzk1Ci0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1djb250cm9scy5weQpAQCAtMCwwICsxLDM3NiBAQAoraW1wb3J0IEN0bAoraW1wb3J0IENvbnRyb2xzCitpbXBvcnQgV2luCitpbXBvcnQgV2Jhc2UKK2ltcG9ydCBRZAoraW1wb3J0IEV2dAorCitjbGFzcyBDb250cm9sV2lkZ2V0KFdiYXNlLkNsaWNrYWJsZVdpZGdldCk6CisKKwlkZWYgX19pbml0X18oc2VsZiwgcG9zc2l6ZSwgdGl0bGUgPSAiQ29udHJvbCIsIHByb2NJRCA9IDAsIGNhbGxiYWNrID0gTm9uZSwgdmFsdWUgPSAwLCBtaW4gPSAwLCBtYXggPSAxKToKKwkJV2Jhc2UuQ2xpY2thYmxlV2lkZ2V0Ll9faW5pdF9fKHNlbGYsIHBvc3NpemUpCisJCXNlbGYuX2NvbnRyb2wgPSBOb25lCisJCXNlbGYuX3RpdGxlID0gdGl0bGUKKwkJc2VsZi5fY2FsbGJhY2sgPSBjYWxsYmFjaworCQlzZWxmLl9wcm9jSUQgPSBwcm9jSUQKKwkJc2VsZi5fdmFsdWUgPSB2YWx1ZQorCQlzZWxmLl9taW4gPSBtaW4KKwkJc2VsZi5fbWF4ID0gbWF4CisJCXNlbGYuX2VuYWJsZWQgPSAxCisJCisJZGVmIG9wZW4oc2VsZik6CisJCXNlbGYuX2NhbGNib3VuZHMoKQorCQlzZWxmLl9jb250cm9sID0gQ3RsLk5ld0NvbnRyb2woc2VsZi5fcGFyZW50d2luZG93LndpZCwgCisJCQkJCQlzZWxmLl9ib3VuZHMsIAorCQkJCQkJc2VsZi5fdGl0bGUsIAorCQkJCQkJMSwgCisJCQkJCQlzZWxmLl92YWx1ZSwgCisJCQkJCQlzZWxmLl9taW4sIAorCQkJCQkJc2VsZi5fbWF4LCAKKwkJCQkJCXNlbGYuX3Byb2NJRCwgCisJCQkJCQkwKQorCQlzZWxmLlNldFBvcnQoKQorCQlXaW4uVmFsaWRSZWN0KHNlbGYuX2JvdW5kcykKKwkJc2VsZi5lbmFibGUoc2VsZi5fZW5hYmxlZCkKKwkKKwlkZWYgYWRqdXN0KHNlbGYsIG9sZGJvdW5kcyk6CisJCXNlbGYuU2V0UG9ydCgpCisJCXNlbGYuX2NvbnRyb2wuSGlkZUNvbnRyb2woKQorCQlzZWxmLl9jb250cm9sLk1vdmVDb250cm9sKHNlbGYuX2JvdW5kc1swXSwgc2VsZi5fYm91bmRzWzFdKQorCQlzZWxmLl9jb250cm9sLlNpemVDb250cm9sKHNlbGYuX2JvdW5kc1syXSAtIHNlbGYuX2JvdW5kc1swXSwgc2VsZi5fYm91bmRzWzNdIC0gc2VsZi5fYm91bmRzWzFdKQorCQlpZiBzZWxmLl92aXNpYmxlOgorCQkJUWQuRXJhc2VSZWN0KHNlbGYuX2JvdW5kcykKKwkJCXNlbGYuX2NvbnRyb2wuU2hvd0NvbnRyb2woKQorCQkJV2luLlZhbGlkUmVjdChzZWxmLl9ib3VuZHMpCisJCisJZGVmIGNsb3NlKHNlbGYpOgorCQlzZWxmLl9jb250cm9sLkhpZGVDb250cm9sKCkKKwkJc2VsZi5fY29udHJvbCA9IE5vbmUKKwkJV2Jhc2UuQ2xpY2thYmxlV2lkZ2V0LmNsb3NlKHNlbGYpCisJCisJZGVmIGVuYWJsZShzZWxmLCBvbm9mZik6CisJCWlmIHNlbGYuX2NvbnRyb2wgYW5kIHNlbGYuX2VuYWJsZWQgPD4gb25vZmY6CisJCQlzZWxmLl9jb250cm9sLkhpbGl0ZUNvbnRyb2woKG5vdCBvbm9mZikgYW5kIDI1NSkKKwkJCXNlbGYuX2VuYWJsZWQgPSBvbm9mZgorCQorCWRlZiBzaG93KHNlbGYsIG9ub2ZmKToKKwkJc2VsZi5fdmlzaWJsZSA9IG9ub2ZmCisJCWZvciB3IGluIHNlbGYuX3dpZGdldHM6CisJCQl3LnNob3cob25vZmYpCisJCWlmIG9ub2ZmOgorCQkJc2VsZi5fY29udHJvbC5TaG93Q29udHJvbCgpCisJCWVsc2U6CisJCQlzZWxmLl9jb250cm9sLkhpZGVDb250cm9sKCkKKwkKKwlkZWYgYWN0aXZhdGUoc2VsZiwgb25vZmYpOgorCQlzZWxmLl9hY3RpdmF0ZWQgPSBvbm9mZgorCQlpZiBzZWxmLl9lbmFibGVkOgorCQkJc2VsZi5fY29udHJvbC5IaWxpdGVDb250cm9sKChub3Qgb25vZmYpIGFuZCAyNTUpCisJCisJZGVmIGRyYXcoc2VsZiwgdmlzUmduID0gTm9uZSk6CisJCWlmIHNlbGYuX3Zpc2libGU6CisJCQlzZWxmLl9jb250cm9sLkRyYXcxQ29udHJvbCgpCisJCisJZGVmIHRlc3Qoc2VsZiwgcG9pbnQpOgorCQljdGx0eXBlLCBjb250cm9sID0gQ3RsLkZpbmRDb250cm9sKHBvaW50LCBzZWxmLl9wYXJlbnR3aW5kb3cud2lkKQorCQlpZiBzZWxmLl9lbmFibGVkIGFuZCBjb250cm9sID09IHNlbGYuX2NvbnRyb2w6CisJCQlyZXR1cm4gMQorCQorCWRlZiBjbGljayhzZWxmLCBwb2ludCwgbW9kaWZpZXJzKToKKwkJaWYgbm90IHNlbGYuX2VuYWJsZWQ6CisJCQlyZXR1cm4KKwkJcGFydCA9IHNlbGYuX2NvbnRyb2wuVHJhY2tDb250cm9sKHBvaW50KQorCQlpZiBwYXJ0OgorCQkJaWYgc2VsZi5fY2FsbGJhY2s6CisJCQkJV2Jhc2UuQ2FsbGJhY2tDYWxsKHNlbGYuX2NhbGxiYWNrLCAwKQorCQorCWRlZiBzZXR0aXRsZShzZWxmLCB0aXRsZSk6CisJCWlmIHNlbGYuX2NvbnRyb2w6CisJCQlzZWxmLl9jb250cm9sLlNldENvbnRyb2xUaXRsZSh0aXRsZSkKKwkJc2VsZi5fdGl0bGUgPSB0aXRsZQorCQorCWRlZiBnZXR0aXRsZShzZWxmKToKKwkJcmV0dXJuIHNlbGYuX3RpdGxlCisKK2NsYXNzIEJ1dHRvbihDb250cm9sV2lkZ2V0KToKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgcG9zc2l6ZSwgdGl0bGUgPSAiQnV0dG9uIiwgY2FsbGJhY2sgPSBOb25lKToKKwkJcHJvY0lEID0gQ29udHJvbHMucHVzaEJ1dFByb2MgfCBDb250cm9scy51c2VXRm9udAorCQlDb250cm9sV2lkZ2V0Ll9faW5pdF9fKHNlbGYsIHBvc3NpemUsIHRpdGxlLCBwcm9jSUQsIGNhbGxiYWNrLCAwLCAwLCAxKQorCQlzZWxmLl9pc2RlZmF1bHQgPSAwCisJCisJZGVmIHB1c2goc2VsZik6CisJCWlmIG5vdCBzZWxmLl9lbmFibGVkOgorCQkJcmV0dXJuCisJCWltcG9ydCB0aW1lCisJCXNlbGYuX2NvbnRyb2wuSGlsaXRlQ29udHJvbCgxKQorCQl0aW1lLnNsZWVwKDAuMSkKKwkJc2VsZi5fY29udHJvbC5IaWxpdGVDb250cm9sKDApCisJCWlmIHNlbGYuX2NhbGxiYWNrOgorCQkJV2Jhc2UuQ2FsbGJhY2tDYWxsKHNlbGYuX2NhbGxiYWNrLCAwKQorCQorCWRlZiBlbmFibGUoc2VsZiwgb25vZmYpOgorCQlpZiBzZWxmLl9jb250cm9sIGFuZCBzZWxmLl9lbmFibGVkIDw+IG9ub2ZmOgorCQkJc2VsZi5fY29udHJvbC5IaWxpdGVDb250cm9sKChub3Qgb25vZmYpIGFuZCAyNTUpCisJCQlzZWxmLl9lbmFibGVkID0gb25vZmYKKwkJCWlmIHNlbGYuX2lzZGVmYXVsdCBhbmQgc2VsZi5fdmlzaWJsZToKKwkJCQlzZWxmLlNldFBvcnQoKQorCQkJCXNlbGYuZHJhd2ZhdGZyYW1lKG9ub2ZmKQorCQorCWRlZiBhY3RpdmF0ZShzZWxmLCBvbm9mZik6CisJCXNlbGYuX2FjdGl2YXRlZCA9IG9ub2ZmCisJCWlmIHNlbGYuX2VuYWJsZWQ6CisJCQlzZWxmLl9jb250cm9sLkhpbGl0ZUNvbnRyb2woKG5vdCBvbm9mZikgYW5kIDI1NSkKKwkJCWlmIHNlbGYuX2lzZGVmYXVsdCBhbmQgc2VsZi5fdmlzaWJsZToKKwkJCQlzZWxmLlNldFBvcnQoKQorCQkJCXNlbGYuZHJhd2ZhdGZyYW1lKG9ub2ZmKQorCQorCWRlZiBzaG93KHNlbGYsIG9ub2ZmKToKKwkJQ29udHJvbFdpZGdldC5zaG93KHNlbGYsIG9ub2ZmKQorCQlpZiBzZWxmLl9pc2RlZmF1bHQ6CisJCQlzZWxmLmRyYXdmYXRmcmFtZShvbm9mZiBhbmQgc2VsZi5fZW5hYmxlZCkKKwkKKwlkZWYgZHJhdyhzZWxmLCB2aXNSZ24gPSBOb25lKToKKwkJaWYgc2VsZi5fdmlzaWJsZToKKwkJCXNlbGYuX2NvbnRyb2wuRHJhdzFDb250cm9sKCkKKwkJCWlmIHNlbGYuX2lzZGVmYXVsdCBhbmQgc2VsZi5fYWN0aXZhdGVkOgorCQkJCXNlbGYuZHJhd2ZhdGZyYW1lKHNlbGYuX2VuYWJsZWQpCisJCisJZGVmIGRyYXdmYXRmcmFtZShzZWxmLCBvbm9mZik6CisJCXN0YXRlID0gUWQuR2V0UGVuU3RhdGUoKQorCQlpZiBvbm9mZjoKKwkJCVFkLlBlblBhdChRZC5xZC5ibGFjaykKKwkJZWxzZToKKwkJCVFkLlBlblBhdChRZC5xZC53aGl0ZSkKKwkJZmF0cmVjdCA9IFFkLkluc2V0UmVjdChzZWxmLl9ib3VuZHMsIC00LCAtNCkKKwkJUWQuUGVuU2l6ZSgzLCAzKQorCQlRZC5GcmFtZVJvdW5kUmVjdChmYXRyZWN0LCAxNiwgMTYpCisJCVFkLlNldFBlblN0YXRlKHN0YXRlKQorCQorCWRlZiBfc2V0ZGVmYXVsdChzZWxmLCBvbm9mZik6CisJCXNlbGYuX2lzZGVmYXVsdCA9IG9ub2ZmCisJCWlmIHNlbGYuX2NvbnRyb2w6CisJCQlzZWxmLlNldFBvcnQoKQorCQkJc2VsZi5kcmF3ZmF0ZnJhbWUob25vZmYpCisJCisJZGVmIGFkanVzdChzZWxmLCBvbGRib3VuZHMpOgorCQlpZiBzZWxmLl9pc2RlZmF1bHQ6CisJCQlvbGQgPSBRZC5JbnNldFJlY3Qob2xkYm91bmRzLCAtNCwgLTQpCisJCQluZXcgPSBRZC5JbnNldFJlY3Qoc2VsZi5fYm91bmRzLCAtNCwgLTQpCisJCQlRZC5FcmFzZVJlY3Qob2xkKQorCQkJV2luLkludmFsUmVjdChvbGQpCisJCQlXaW4uSW52YWxSZWN0KG5ldykKKwkJQ29udHJvbFdpZGdldC5hZGp1c3Qoc2VsZiwgb2xkYm91bmRzKQorCisKK2NsYXNzIENoZWNrQm94KENvbnRyb2xXaWRnZXQpOgorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBwb3NzaXplLCB0aXRsZSA9ICJDaGVja2JveCIsIGNhbGxiYWNrID0gTm9uZSwgdmFsdWUgPSAwKToKKwkJcHJvY0lEID0gQ29udHJvbHMuY2hlY2tCb3hQcm9jIHwgQ29udHJvbHMudXNlV0ZvbnQKKwkJQ29udHJvbFdpZGdldC5fX2luaXRfXyhzZWxmLCBwb3NzaXplLCB0aXRsZSwgcHJvY0lELCBjYWxsYmFjaywgdmFsdWUsIDAsIDEpCisJCisJZGVmIGNsaWNrKHNlbGYsIHBvaW50LCBtb2RpZmllcnMpOgorCQlpZiBub3Qgc2VsZi5fZW5hYmxlZDoKKwkJCXJldHVybgorCQlwYXJ0ID0gc2VsZi5fY29udHJvbC5UcmFja0NvbnRyb2wocG9pbnQpCisJCWlmIHBhcnQ6CisJCQlzZWxmLnRvZ2dsZSgpCisJCQlpZiBzZWxmLl9jYWxsYmFjazoKKwkJCQlXYmFzZS5DYWxsYmFja0NhbGwoc2VsZi5fY2FsbGJhY2ssIDAsIHNlbGYuZ2V0KCkpCisJCisJZGVmIHB1c2goc2VsZik6CisJCWlmIG5vdCBzZWxmLl9lbmFibGVkOgorCQkJcmV0dXJuCisJCXNlbGYudG9nZ2xlKCkKKwkJaWYgc2VsZi5fY2FsbGJhY2s6CisJCQlXYmFzZS5DYWxsYmFja0NhbGwoc2VsZi5fY2FsbGJhY2ssIDAsIHNlbGYuZ2V0KCkpCisJCisJZGVmIHRvZ2dsZShzZWxmKToKKwkJc2VsZi5zZXQobm90IHNlbGYuZ2V0KCkpCisJCisJZGVmIHNldChzZWxmLCB2YWx1ZSk6CisJCWlmIHNlbGYuX2NvbnRyb2w6CisJCQlzZWxmLl9jb250cm9sLlNldENvbnRyb2xWYWx1ZSh2YWx1ZSkKKwkJZWxzZToKKwkJCXNlbGYuX3ZhbHVlID0gdmFsdWUKKwkKKwlkZWYgZ2V0KHNlbGYpOgorCQlpZiBzZWxmLl9jb250cm9sOgorCQkJcmV0dXJuIHNlbGYuX2NvbnRyb2wuR2V0Q29udHJvbFZhbHVlKCkKKwkJZWxzZToKKwkJCXJldHVybiBzZWxmLl92YWx1ZQorCQorCitjbGFzcyBSYWRpb0J1dHRvbihDb250cm9sV2lkZ2V0KToKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgcG9zc2l6ZSwgdGl0bGUgPSAiUmFkaW9idXR0b24iLCB0aGVidXR0b25zLCBjYWxsYmFjayA9IE5vbmUsIHZhbHVlID0gMCk6CisJCXByb2NJRCA9IENvbnRyb2xzLnJhZGlvQnV0UHJvYyB8IENvbnRyb2xzLnVzZVdGb250CisJCUNvbnRyb2xXaWRnZXQuX19pbml0X18oc2VsZiwgcG9zc2l6ZSwgdGl0bGUsIHByb2NJRCwgY2FsbGJhY2ssIHZhbHVlLCAwLCAxKQorCQlzZWxmLnRoZWJ1dHRvbnMgPSB0aGVidXR0b25zCisJCXRoZWJ1dHRvbnMuYXBwZW5kKHNlbGYpCisJCisJZGVmIGNsb3NlKHNlbGYpOgorCQlzZWxmLnRoZWJ1dHRvbnMgPSBOb25lCisJCUNvbnRyb2xXaWRnZXQuY2xvc2Uoc2VsZikKKwkKKwlkZWYgY2xpY2soc2VsZiwgcG9pbnQsIG1vZGlmaWVycyk6CisJCWlmIG5vdCBzZWxmLl9lbmFibGVkOgorCQkJcmV0dXJuCisJCXBhcnQgPSBzZWxmLl9jb250cm9sLlRyYWNrQ29udHJvbChwb2ludCkKKwkJaWYgcGFydDoKKwkJCXNlbGYuc2V0KDEpCisJCQlpZiBzZWxmLl9jYWxsYmFjazoKKwkJCQlXYmFzZS5DYWxsYmFja0NhbGwoc2VsZi5fY2FsbGJhY2ssIDAsIDEpCisJCisJZGVmIHB1c2goc2VsZik6CisJCWlmIG5vdCBzZWxmLl9lbmFibGVkOgorCQkJcmV0dXJuCisJCXNlbGYuc2V0KDEpCisJCWlmIHNlbGYuX2NhbGxiYWNrOgorCQkJV2Jhc2UuQ2FsbGJhY2tDYWxsKHNlbGYuX2NhbGxiYWNrLCAwLCAxKQorCQorCWRlZiBzZXQoc2VsZiwgdmFsdWUpOgorCQlmb3IgYnV0dG9uIGluIHNlbGYudGhlYnV0dG9uczoKKwkJCWlmIGJ1dHRvbi5fY29udHJvbDoKKwkJCQlidXR0b24uX2NvbnRyb2wuU2V0Q29udHJvbFZhbHVlKGJ1dHRvbiA9PSBzZWxmKQorCQkJZWxzZToKKwkJCQlidXR0b24uX3ZhbHVlID0gKGJ1dHRvbiA9PSBzZWxmKQorCQorCWRlZiBnZXQoc2VsZik6CisJCWlmIHNlbGYuX2NvbnRyb2w6CisJCQlyZXR1cm4gc2VsZi5fY29udHJvbC5HZXRDb250cm9sVmFsdWUoKQorCQllbHNlOgorCQkJcmV0dXJuIHNlbGYuX3ZhbHVlCisJCisKK2NsYXNzIFNjcm9sbGJhcihDb250cm9sV2lkZ2V0KToKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgcG9zc2l6ZSwgY2FsbGJhY2sgPSBOb25lLCB2YWx1ZSA9IDAsIG1pbiA9IDAsIG1heCA9IDApOgorCQlwcm9jSUQgPSBDb250cm9scy5zY3JvbGxCYXJQcm9jCisJCUNvbnRyb2xXaWRnZXQuX19pbml0X18oc2VsZiwgcG9zc2l6ZSwgIiIsIHByb2NJRCwgY2FsbGJhY2ssIHZhbHVlLCBtaW4sIG1heCkKKwkKKwkjIGludGVyZmFjZQorCWRlZiBzZXQoc2VsZiwgdmFsdWUpOgorCQlpZiBzZWxmLl9jYWxsYmFjazoKKwkJCVdiYXNlLkNhbGxiYWNrQ2FsbChzZWxmLl9jYWxsYmFjaywgMSwgdmFsdWUpCisJCisJZGVmIHVwKHNlbGYpOgorCQlpZiBzZWxmLl9jYWxsYmFjazoKKwkJCVdiYXNlLkNhbGxiYWNrQ2FsbChzZWxmLl9jYWxsYmFjaywgMSwgJysnKQorCQorCWRlZiBkb3duKHNlbGYpOgorCQlpZiBzZWxmLl9jYWxsYmFjazoKKwkJCVdiYXNlLkNhbGxiYWNrQ2FsbChzZWxmLl9jYWxsYmFjaywgMSwgJy0nKQorCQorCWRlZiBwYWdldXAoc2VsZik6CisJCWlmIHNlbGYuX2NhbGxiYWNrOgorCQkJV2Jhc2UuQ2FsbGJhY2tDYWxsKHNlbGYuX2NhbGxiYWNrLCAxLCAnKysnKQorCQorCWRlZiBwYWdlZG93bihzZWxmKToKKwkJaWYgc2VsZi5fY2FsbGJhY2s6CisJCQlXYmFzZS5DYWxsYmFja0NhbGwoc2VsZi5fY2FsbGJhY2ssIDEsICctLScpCisJCisJZGVmIHNldG1pbihzZWxmLCBtaW4pOgorCQlzZWxmLl9jb250cm9sLlNldENvbnRyb2xNaW5pbXVtKG1pbikKKwkKKwlkZWYgc2V0bWF4KHNlbGYsIG1pbik6CisJCXNlbGYuX2NvbnRyb2wuU2V0Q29udHJvbE1pbmltdW0obWF4KQorCQorCWRlZiBnZXRtaW4oc2VsZik6CisJCXJldHVybiBzZWxmLl9jb250cm9sLkdldENvbnRyb2xNaW5pbXVtKCkKKwkKKwlkZWYgZ2V0bWF4KHNlbGYpOgorCQlyZXR1cm4gc2VsZi5fY29udHJvbC5HZXRDb250cm9sTWluaW11bSgpCisJCisJIyBpbnRlcm5hbHMKKwlkZWYgY2xpY2soc2VsZiwgcG9pbnQsIG1vZGlmaWVycyk6CisJCWlmIG5vdCBzZWxmLl9lbmFibGVkOgorCQkJcmV0dXJuCisJCSMgY3VzdG9tIFRyYWNrQ29udHJvbC4gQSBtb3VzZWRvd24gaW4gYSBzY3JvbGxiYXIgYXJyb3cgb3IgcGFnZSBhcmVhIHNob3VsZAorCQkjIGdlbmVyYXRlIF9jb250cm9sIGhpdHMgYXMgbG9uZyBhcyB0aGUgbW91c2UgaXMgYSkgZG93biwgYikgc3RpbGwgaW4gdGhlIHNhbWUgcGFydAorCQlwYXJ0ID0gc2VsZi5fY29udHJvbC5UZXN0Q29udHJvbChwb2ludCkKKwkJaWYgQ29udHJvbHMuaW5VcEJ1dHRvbiA8PSBwYXJ0IDw9IENvbnRyb2xzLmluUGFnZURvd246CQorCQkJc2VsZi5fY29udHJvbC5IaWxpdGVDb250cm9sKHBhcnQpCisJCQlzZWxmLl9oaXQocGFydCkKKwkJCW9sZHBhcnQgPSBwYXJ0CisJCQl3aGlsZSBFdnQuU3RpbGxEb3duKCk6CisJCQkJcGFydCA9IHNlbGYuX2NvbnRyb2wuVGVzdENvbnRyb2wocG9pbnQpCisJCQkJaWYgcGFydCA9PSBvbGRwYXJ0OgorCQkJCQlzZWxmLl9jb250cm9sLkhpbGl0ZUNvbnRyb2wocGFydCkKKwkJCQkJc2VsZi5faGl0KHBhcnQpCisJCQkJZWxzZToKKwkJCQkJc2VsZi5fY29udHJvbC5IaWxpdGVDb250cm9sKDApCisJCQkJc2VsZi5TZXRQb3J0KCkKKwkJCQlwb2ludCA9IEV2dC5HZXRNb3VzZSgpCisJCQlzZWxmLl9jb250cm9sLkhpbGl0ZUNvbnRyb2woMCkKKwkJZWxpZiBwYXJ0ID09IENvbnRyb2xzLmluVGh1bWI6CisJCQlwYXJ0ID0gc2VsZi5fY29udHJvbC5UcmFja0NvbnRyb2wocG9pbnQpCisJCQlpZiBwYXJ0OgorCQkJCXNlbGYuX2hpdChwYXJ0KQorCQorCWRlZiBfaGl0KHNlbGYsIHBhcnQpOgorCQlpZiBwYXJ0ID09IENvbnRyb2xzLmluVGh1bWI6CisJCQl2YWx1ZSA9IHNlbGYuX2NvbnRyb2wuR2V0Q29udHJvbFZhbHVlKCkKKwkJZWxpZiBwYXJ0ID09IENvbnRyb2xzLmluVXBCdXR0b246CisJCQl2YWx1ZSA9ICIrIgorCQllbGlmIHBhcnQgPT0gQ29udHJvbHMuaW5Eb3duQnV0dG9uOgorCQkJdmFsdWUgPSAiLSIKKwkJZWxpZiBwYXJ0ID09IENvbnRyb2xzLmluUGFnZVVwOgorCQkJdmFsdWUgPSAiKysiCisJCWVsaWYgcGFydCA9PSBDb250cm9scy5pblBhZ2VEb3duOgorCQkJdmFsdWUgPSAiLS0iCisJCWlmIHNlbGYuX2NhbGxiYWNrOgorCQkJV2Jhc2UuQ2FsbGJhY2tDYWxsKHNlbGYuX2NhbGxiYWNrLCAxLCB2YWx1ZSkKKwkKKwlkZWYgZHJhdyhzZWxmLCB2aXNSZ24gPSBOb25lKToKKwkJaWYgc2VsZi5fdmlzaWJsZToKKwkJCXNlbGYuX2NvbnRyb2wuRHJhdzFDb250cm9sKCkKKwkJCVFkLkZyYW1lUmVjdChzZWxmLl9ib3VuZHMpCisJCisJZGVmIGFkanVzdChzZWxmLCBvbGRib3VuZHMpOgorCQlzZWxmLlNldFBvcnQoKQorCQlXaW4uSW52YWxSZWN0KG9sZGJvdW5kcykKKwkJc2VsZi5fY29udHJvbC5IaWRlQ29udHJvbCgpCisJCXNlbGYuX2NvbnRyb2wuTW92ZUNvbnRyb2woc2VsZi5fYm91bmRzWzBdLCBzZWxmLl9ib3VuZHNbMV0pCisJCXNlbGYuX2NvbnRyb2wuU2l6ZUNvbnRyb2woc2VsZi5fYm91bmRzWzJdIC0gc2VsZi5fYm91bmRzWzBdLCBzZWxmLl9ib3VuZHNbM10gLSBzZWxmLl9ib3VuZHNbMV0pCisJCWlmIHNlbGYuX3Zpc2libGU6CisJCQlRZC5FcmFzZVJlY3Qoc2VsZi5fYm91bmRzKQorCQkJaWYgc2VsZi5fYWN0aXZhdGVkOgorCQkJCXNlbGYuX2NvbnRyb2wuU2hvd0NvbnRyb2woKQorCQkJZWxzZToKKwkJCQlRZC5GcmFtZVJlY3Qoc2VsZi5fYm91bmRzKQorCQkJV2luLlZhbGlkUmVjdChzZWxmLl9ib3VuZHMpCisJCisJZGVmIGFjdGl2YXRlKHNlbGYsIG9ub2ZmKToKKwkJc2VsZi5fYWN0aXZhdGVkID0gb25vZmYKKwkJaWYgc2VsZi5fdmlzaWJsZToKKwkJCWlmIG9ub2ZmOgorCQkJCXNlbGYuX2NvbnRyb2wuU2hvd0NvbnRyb2woKQorCQkJZWxzZToKKwkJCQlzZWxmLl9jb250cm9sLkhpZGVDb250cm9sKCkKKwkJCQlzZWxmLmRyYXcoTm9uZSkKKwkJCQlXaW4uVmFsaWRSZWN0KHNlbGYuX2JvdW5kcykKKwkJCisJZGVmIHNldChzZWxmLCB2YWx1ZSk6CisJCWlmIHNlbGYuX2NvbnRyb2w6CisJCQlzZWxmLl9jb250cm9sLlNldENvbnRyb2xWYWx1ZSh2YWx1ZSkKKwkJZWxzZToKKwkJCXNlbGYuX3ZhbHVlID0gdmFsdWUKKwkKKwlkZWYgZ2V0KHNlbGYpOgorCQlpZiBzZWxmLl9jb250cm9sOgorCQkJcmV0dXJuIHNlbGYuX2NvbnRyb2wuR2V0Q29udHJvbFZhbHVlKCkKKwkJZWxzZToKKwkJCXJldHVybiBzZWxmLl92YWx1ZQorCQorCitkZWYgX3NjYWxlYmFydmFsdWUoYWJzbWluLCBhYnNtYXgsIGN1cm1pbiwgY3VybWF4KToKKwlpZiBjdXJtaW4gPD0gYWJzbWluIGFuZCBjdXJtYXggPj0gYWJzbWF4OgorCQlyZXR1cm4gTm9uZQorCWlmIGN1cm1pbiA8PSBhYnNtaW46CisJCXJldHVybiAwCisJaWYgY3VybWF4ID49IGFic21heDoKKwkJcmV0dXJuIDMyNzY3CisJcGVyYyA9IGZsb2F0KGN1cm1pbi1hYnNtaW4pIC8gZmxvYXQoKGFic21heCAtIGFic21pbikgLSAoY3VybWF4IC0gY3VybWluKSkKKwlyZXR1cm4gaW50KHBlcmMqMzI3NjcpCisKZGlmZiAtLWdpdCBhL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XZGlhbG9ncy5weSBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XZGlhbG9ncy5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5iOTU0MjU1Ci0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1dkaWFsb2dzLnB5CkBAIC0wLDAgKzEsMTgzIEBACitpbXBvcnQgVworZnJvbSB0eXBlcyBpbXBvcnQgKgoraW1wb3J0IHN0cmluZworCisiIiIKK2ltcG9ydCBXZGlhbG9ncwordGVzdERpY3QxID0gezE6MSwgMjoyLCAzOjN9Cit0ZXN0RGljdDIgPSB7MzozLDQ6NCwgJ3Rlc3REaWN0MSc6dGVzdERpY3QxLCA2OjYsIDc6N30KK3Rlc3REaWN0MyA9IHszOjMsNDo0LCAndGVzdERpY3QyJzp0ZXN0RGljdDIsICd0ZXN0RGljdDEnOnRlc3REaWN0MSwgNjo2LCA3Ojd9CitXZGlhbG9ncy5FZGl0RGljdGlvbmFyeSh0ZXN0RGljdDMpCisKK2ltcG9ydCBXZGlhbG9ncworYSA9IFdkaWFsb2dzLkFzaygneHh4JywgJ2RlZmF1bHQgdGV4dCcsIFsnZm9udCcsICd0eXBvZ3JhZmllJywgJ2xldHRlcnRvbndlcnBlbicsICdodWlzc3RpamwnXSkKKyIiIgorCitkZWYgTWVzc2FnZSh0ZXh0LCBidXR0b24gPSAiT0siKToKKwl3ID0gVy5Nb2RhbERpYWxvZygoMzAwLCAxMDApKQorCXcuYnV0dG9uID0gVy5CdXR0b24oKC05MCwgLTMwLCA4MCwgMTYpLCBidXR0b24sIHcuY2xvc2UpCisJdy5tZXNzYWdlID0gVy5UZXh0Qm94KCgxMCwgMTAsIC0xMCwgLTQwKSwgdGV4dCkKKwl3LnNldGRlZmF1bHRidXR0b24ody5idXR0b24pCisJdy5vcGVuKCkKKworCitkZWYgQXNrKHF1ZXN0aW9uLCBkZWZhdWx0dGV4dCA9ICIiLCBzZWxlY3Rpb25zID0gW10pOgorCWQgPSBfQXNrKHF1ZXN0aW9uLCBkZWZhdWx0dGV4dCwgc2VsZWN0aW9ucykKKwlyZXR1cm4gZC5ydgorCisKK2NsYXNzIF9Bc2s6CisJIwlzZWxlY3Rpb25zIGlzIGEgbGlzdCBvZiBwb3NzaWJsZSBmb3Igc2VsZWN0aW9ucworCQorCWRlZiBfX2luaXRfXyhzZWxmLCBxdWVzdGlvbiwgZGVmYXVsdHRleHQsIHNlbGVjdGlvbnMpOgorCQlzZWxmLnNlbGVjdGlvbnMgPSBbXQorCQlmb3IgcyBpbiBzZWxlY3Rpb25zOgorCQkJc2VsZi5zZWxlY3Rpb25zLmFwcGVuZChzdHJpbmcubG93ZXIocykpCisJCXNlbGYuc2VsZWN0aW9ucy5zb3J0KCkKKwkJc2VsZi53ID0gVy5Nb2RhbERpYWxvZygoMzAwLCAxMjApKQorCQlzZWxmLncuYnV0dG9uMSA9IFcuQnV0dG9uKCgtOTAsIC0zMCwgODAsIDE2KSwgIk9LIiwgc2VsZi5idXR0b24xaGl0KQorCQlzZWxmLncuYnV0dG9uMiA9IFcuQnV0dG9uKCgtMTgwLCAtMzAsIDgwLCAxNiksICJDYW5jZWwiLCBzZWxmLmJ1dHRvbjJoaXQpCisJCXNlbGYudy5xdWVzdGlvbiA9IFcuVGV4dEJveCgoMTAsIDEwLCAtMTAsIDMwKSwgcXVlc3Rpb24pCisJCXNlbGYudy5pbnB1dCA9IFcuRWRpdFRleHQoKDEwLCA0MCwgLTEwLCAyMCksIGRlZmF1bHR0ZXh0LCBzZWxmLnByb2Nlc3NJbnB1dCkKKwkJc2VsZi5ydiA9IE5vbmUKKwkJc2VsZi53LnNldGRlZmF1bHRidXR0b24oc2VsZi53LmJ1dHRvbjEpCisJCQorCQlzZWxmLncuYmluZCgiY21kLiIsIHNlbGYudy5idXR0b24yLnB1c2gpCisJCXNlbGYudy5vcGVuKCkKKwkKKwlkZWYgcHJvY2Vzc0lucHV0KHNlbGYsIGtleSwgbW9kaWZpZXJzKToJIyBQcm9jZXNzIHVzZXIgaW5wdXQgdG8gbWF0Y2ggYSBzZWxlY3Rpb24KKwkJcG9zID0gc2VsZi53LmlucHV0LmdldHNlbGVjdGlvbigpCisJCWlucHV0ID0gc3RyaW5nLmxvd2VyKHNlbGYudy5pbnB1dC5nZXQoKVswOnBvc1sxXV0pCisJCWlmIGxlbihpbnB1dCk6CisJCQlmb3IgdCBpbiBzZWxmLnNlbGVjdGlvbnM6CisJCQkJaWYgaW5wdXQgPT0gdFswOnBvc1swXV06CisJCQkJCXNlbGYudy5pbnB1dC5zZXQodCkKKwkJCQkJc2VsZi53LmlucHV0LnNldHNlbGVjdGlvbihwb3NbMF0sIHBvc1sxXSkKKwkJCQkJcmV0dXJuCisJCXNlbGYudy5pbnB1dC5zZXQoaW5wdXQpCisJCXNlbGYudy5pbnB1dC5zZXRzZWxlY3Rpb24ocG9zWzFdLCBwb3NbMV0pCisJCQorCWRlZiBidXR0b24xaGl0KHNlbGYpOgorCQlzZWxmLnJ2ID0gc2VsZi53LmlucHV0LmdldCgpCisJCXNlbGYudy5jbG9zZSgpCisJCQorCWRlZiBidXR0b24yaGl0KHNlbGYpOgorCQlzZWxmLncuY2xvc2UoKQorCitjbGFzcyBfQXNrWWVzTm86CisJCisJZGVmIF9faW5pdF9fKHNlbGYsIHF1ZXN0aW9uLCBjYW5jZWxGbGFnPSAwKToKKwkJaWYgY2FuY2VsRmxhZzoKKwkJCXNpemUgPSAxOTAsIDgwCisJCWVsc2U6CXNpemUgPSAxNTAsIDgwCisJCXNlbGYudyA9IFcuTW9kYWxEaWFsb2coc2l6ZSkKKwkJc2VsZi53LnllcyA9IFcuQnV0dG9uKCgxMCwgLTM2LCA1MCwgMjQpLCAnWWVzJywgc2VsZi55ZXMpCisJCWlmIGNhbmNlbEZsYWc6CisJCQlzZWxmLncuY2FuY2VsID0gVy5CdXR0b24oKDcwLCAtMzYsIC03MCwgMjQpLCAiQ2FuY2VsIiwgc2VsZi5jYW5jZWwpCQorCQlzZWxmLncubm8gPSBXLkJ1dHRvbigoLTYwLCAtMzYsIC0xMCwgMjQpLCAnTm8nLCBzZWxmLm5vKQorCQlzZWxmLncucXVlc3Rpb24gPSBXLlRleHRCb3goKDEwLCAxMCwgLTEwLCAzMCksIHF1ZXN0aW9uKQorCQlzZWxmLnJ2ID0gTm9uZQorCQlzZWxmLncuc2V0ZGVmYXVsdGJ1dHRvbihzZWxmLncueWVzKQorCQlpZiBjYW5jZWxGbGFnOgorCQkJc2VsZi53LmJpbmQoImNtZC4iLCBzZWxmLncuY2FuY2VsKQorCQllbHNlOglzZWxmLncuYmluZCgiY21kLiIsIHNlbGYudy5ubykKKwkJc2VsZi53Lm9wZW4oKQorCQorCWRlZiB5ZXMoc2VsZik6CisJCXNlbGYucnYgPSAxCisJCXNlbGYudy5jbG9zZSgpCisJCQorCWRlZiBubyhzZWxmKToKKwkJc2VsZi5ydiA9IDAKKwkJc2VsZi53LmNsb3NlKCkKKworCWRlZiBjYW5jZWwoc2VsZik6CisJCXNlbGYucnYgPSAtMQorCQlzZWxmLncuY2xvc2UoKQorCitkZWYgQXNrWWVzTm8ocXVlc3Rpb24pOgorCWQgPSBfQXNrWWVzTm8ocXVlc3Rpb24sIDApCisJcmV0dXJuIGQucnYKKwkKK2RlZiBBc2tZZXNDYW5jZWxObyhxdWVzdGlvbik6CisJZCA9IF9Bc2tZZXNObyhxdWVzdGlvbiwgMSkKKwlyZXR1cm4gZC5ydgorCQorY2xhc3MgQ2FsbEJhY2tCdXR0b24oVy5CdXR0b24pOgorCWRlZiBjbGljayhzZWxmLCBwb2ludCwgbW9kaWZpZXJzKToKKwkJaWYgbm90IHNlbGYuX2VuYWJsZWQ6CisJCQlyZXR1cm4KKwkJcGFydCA9IHNlbGYuX2NvbnRyb2wuVHJhY2tDb250cm9sKHBvaW50KQorCQlpZiBwYXJ0OgorCQkJaWYgc2VsZi5fY2FsbGJhY2s6CisJCQkJc2VsZi5fY2FsbGJhY2soc2VsZi5kaWN0KQorCQorCWRlZiBwdXNoKHNlbGYpOgorCQlpZiBub3Qgc2VsZi5fZW5hYmxlZDoKKwkJCXJldHVybgorCQlpbXBvcnQgdGltZQorCQlzZWxmLl9jb250cm9sLkhpbGl0ZUNvbnRyb2woMSkKKwkJdGltZS5zbGVlcCgwLjEpCisJCXNlbGYuX2NvbnRyb2wuSGlsaXRlQ29udHJvbCgwKQorCQlpZiBzZWxmLl9jYWxsYmFjazoKKwkJCXNlbGYuX2NhbGxiYWNrKHNlbGYuZGljdCkKKwkJCitjbGFzcyBFZGl0RGljdGlvbmFyeToJCQkjIEF1dG8gbGF5b3V0IGVkaXRvciBvZiBkaWN0aW9uYXJ5CisJZGVmIF9faW5pdF9fKHNlbGYsIGRpY3Rpb25hcnksIHRpdGxlID0gJ0RpY3Rpb25hcnkgRWRpdG9yJyk6CisJCXNlbGYubGVhZGluZyA9IDIwCisJCXNlbGYuZCA9IGRpY3Rpb25hcnkKKwkJa2V5cyA9IHNlbGYuZC5rZXlzKCkKKwkJd2luZG93U2l6ZSA9IDQwMCwgbGVuKGtleXMpICogc2VsZi5sZWFkaW5nICsgMTAwCisJCXNlbGYudyA9IHcgPSBXLk1vZGFsRGlhbG9nKHdpbmRvd1NpemUpCisJCXkgPSAyICogc2VsZi5sZWFkaW5nCisJCXRoZUZvbnQgPSBmb250c2V0dGluZ3MgPSAoJ0dlbmV2YScsIDAsIDEwLCAoMCwwLDApKQorCQlrZXlzLnNvcnQoKQorCQlmb3Iga2V5IGluIGtleXM6CisJCQlpZiB0eXBlKGtleSkgPT0gU3RyaW5nVHlwZToKKwkJCQlsYWJlbCA9IGtleQorCQkJZWxzZToJbGFiZWwgPSBga2V5YAorCQkJaWYgdHlwZShzZWxmLmRba2V5XSkgPT0gU3RyaW5nVHlwZToKKwkJCQl2YWx1ZSA9IHNlbGYuZFtrZXldCisJCQllbHNlOgorCQkJCXZhbHVlID0gYHNlbGYuZFtrZXldYAkJIyBKdXN0IHNob3cgdGhlIHZhbHVlCisJCQkKKwkJCWlmIHR5cGUoc2VsZi5kW2tleV0pID09IERpY3RUeXBlOgkjIE1ha2UgYSBidXR0b24KKwkJCQlidXR0b24gPSB3W2xhYmVsXSA9IENhbGxCYWNrQnV0dG9uKCgxMTAsIHksIDUwLCAxOCksIGxhYmVsLCBzZWxmLnB1c2hEaWN0KQorCQkJCWJ1dHRvbi5kaWN0ID0gc2VsZi5kW2tleV0KKwkJCWVsc2U6CisJCQkJd1sna18nICsgbGFiZWxdID0gVy5UZXh0Qm94KCgxMCwgeSwgMjAwLCAxOCksIGxhYmVsLCBmb250c2V0dGluZ3MgPSB0aGVGb250KQorCQkJCXdbbGFiZWxdID0gVy5FZGl0VGV4dCgoMTEwLCB5LCAtMTAsIDE4KSwgdmFsdWUsIGZvbnRzZXR0aW5ncyA9IHRoZUZvbnQpCisJCQl5ID0geSArIHNlbGYubGVhZGluZworCQkKKwkJdy5fbmFtZSA9IFcuVGV4dEJveCgoMTAsIDQsIDEwMCwgMTApLCB0aXRsZSkKKwkJdy5fb2sgPSBXLkJ1dHRvbigoLTE2MCwgLTM2LCA2MCwgMjQpLCAiT0siLCBzZWxmLm9rKQorCQl3Ll9jYW5jZWwgPSBXLkJ1dHRvbigoLTgwLCAtMzYsIDYwLCAyNCksICJDYW5jZWwiLCBzZWxmLmNhbmNlbCkKKwkJdy5zZXRkZWZhdWx0YnV0dG9uKHNlbGYudy5fb2spCisKKwkJc2VsZi5ydiA9IE5vbmUJIyBSZXR1cm4gdmFsdWUKKwkJdy5vcGVuKCkKKwkKKwlkZWYgcHVzaERpY3Qoc2VsZiwgZGljdCk6CisJCUVkaXREaWN0aW9uYXJ5KGRpY3QpCisJCQorCWRlZiBwb3BEaWN0KHNlbGYpOgorCQlzZWxmLncuY2xvc2UoKQorCQkKKwlkZWYgb2soc2VsZik6CisJCXNlbGYucnYgPSAxCisJCWZvciBrZXkgaW4gc2VsZi5kLmtleXMoKToKKwkJCWlmIHR5cGUoa2V5KSA9PSBTdHJpbmdUeXBlOgorCQkJCWxhYmVsID0ga2V5CisJCQllbHNlOglsYWJlbCA9IGBrZXlgCisJCQlpZiB0eXBlKHNlbGYuZFtrZXldKSA9PSBTdHJpbmdUeXBlIG9yIHNlbGYuZFtrZXldID09IE5vbmU6CisJCQkJc2VsZi5kW2tleV0gPSBzZWxmLndbbGFiZWxdLmdldCgpCisJCQllbHNlOgkKKwkJCQl0cnk6CisJCQkJCXNlbGYuZFtrZXldID0gZXZhbChzZWxmLndbbGFiZWxdLmdldCgpKQorCQkJCWV4Y2VwdDoKKwkJCQkJcGFzcworCQlzZWxmLnBvcERpY3QoKQorCQkKKwlkZWYgY2FuY2VsKHNlbGYpOgorCQlzZWxmLnJ2ID0gMAorCQlzZWxmLnBvcERpY3QoKQpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1dncmlkLnB5IGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1dncmlkLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmVmZDdjYjkKLS0tIC9kZXYvbnVsbAorKysgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvV2dyaWQucHkKQEAgLTAsMCArMSwzMyBAQAorIiIiZ3JpZCB1dGlsaXR5IGZvciB3aWRnZXRzIiIiCisKK2NsYXNzIEdyaWQ6CisJCisJZGVmIF9faW5pdF9fKHNlbGYsIAluY29sID0gTm9uZSwgCisJCQkJbWlubmNvbCA9IE5vbmUsCisJCQkJbWF4bmNvbCA9IE5vbmUsCisJCQkJY29sd2lkdGggPSBOb25lLCAKKwkJCQltaW5jb2x3aWR0aCA9IE5vbmUsIAorCQkJCW1heGNvbHdpZHRoID0gTm9uZSwgCisJCQkJd2lkdGggPSBOb25lLCAKKwkJCQltaW53aWR0aCA9IE5vbmUsIAorCQkJCW1heHdpZHRoID0gTm9uZSwgCisJCQkJdmdyaWQgPSA4LCAKKwkJCQlndXR0ZXIgPSAxMCwKKwkJCQlsZWZ0bWFyZ2luID0gTm9uZSwKKwkJCQlyaWdodG1hcmdpbiA9IE5vbmUsCisJCQkJdG9wbWFyZ2luID0gTm9uZSwKKwkJCQlib3R0b21tYXJnaW4gPSBOb25lCisJCQkJKToKKwkJaWYgbGVmdG1hcmdpbiA9PSBOb25lOgorCQkJbGVmdG1hcmdpbiA9IGd1dHRlcgorCQlpZiByaWdodG1hcmdpbiA9PSBOb25lOgorCQkJcmlnaHRtYXJnaW4gPSBndXR0ZXIKKwkJaWYgdG9wbWFyZ2luID09IE5vbmU6CisJCQl0b3BtYXJnaW4gPSB2Z3JpZAorCQlpZiBib3R0b21tYXJnaW4gPT0gTm9uZToKKwkJCWJvdHRvbW1hcmdpbiA9IHZncmlkCisJCisJZGVmIGdldGJvdW5kcyhzZWxmLCB3aWR0aCwgaGVpZ2h0LCBib3VuZHMpOgorCQl4eHgKKworCmRpZmYgLS1naXQgYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvV2xpc3QucHkgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvV2xpc3QucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMDI4ZTg3OAotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XbGlzdC5weQpAQCAtMCwwICsxLDQyNSBAQAoraW1wb3J0IFdiYXNlCitpbXBvcnQgU2NyYXAKK2Zyb20gU3BlY2lhbEtleXMgaW1wb3J0ICoKK2ltcG9ydCBzdHJpbmcKK2ltcG9ydCBFdnQKK2ltcG9ydCBFdmVudHMKK2ltcG9ydCBRZAoraW1wb3J0IFdpbgorCisKK2NsYXNzIExpc3QoV2Jhc2UuU2VsZWN0YWJsZVdpZGdldCk6CisJCisJTERFRl9JRCA9IDAKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgcG9zc2l6ZSwgaXRlbXMgPSBOb25lLCBjYWxsYmFjayA9IE5vbmUsIGZsYWdzID0gMCwgY29scyA9IDEpOgorCQlpZiBpdGVtcyBpcyBOb25lOgorCQkJaXRlbXMgPSBbXQorCQlzZWxmLml0ZW1zID0gaXRlbXMKKwkJV2Jhc2UuU2VsZWN0YWJsZVdpZGdldC5fX2luaXRfXyhzZWxmLCBwb3NzaXplKQorCQlzZWxmLl9zZWxlY3RlZCA9IDAKKwkJc2VsZi5fZW5hYmxlZCA9IDEKKwkJc2VsZi5fbGlzdCA9IE5vbmUKKwkJc2VsZi5fY29scyA9IGNvbHMKKwkJc2VsZi5fY2FsbGJhY2sgPSBjYWxsYmFjaworCQlzZWxmLl9mbGFncyA9IGZsYWdzCisJCXNlbGYubGFzdHR5cGluZyA9ICIiCisJCXNlbGYubGFzdHRpbWUgPSBFdnQuVGlja0NvdW50KCkKKwkJc2VsZi50aW1lbGltaXQgPSAzMAorCQlzZWxmLnNldGl0ZW1zKGl0ZW1zKQorCQlzZWxmLmRyYXdpbmdtb2RlID0gMAorCQorCWRlZiBvcGVuKHNlbGYpOgorCQlzZWxmLnNldGRyYXdpbmdtb2RlKDApCisJCXNlbGYuY3JlYXRlbGlzdCgpCisJCXNlbGYuc2V0ZHJhd2luZ21vZGUoMSkKKwkKKwlkZWYgY3JlYXRlbGlzdChzZWxmKToKKwkJaW1wb3J0IExpc3QKKwkJc2VsZi5fY2FsY2JvdW5kcygpCisJCXNlbGYuU2V0UG9ydCgpCisJCXJlY3QgPSBzZWxmLl9ib3VuZHMKKwkJcmVjdCA9IHJlY3RbMF0rMSwgcmVjdFsxXSsxLCByZWN0WzJdLTE2LCByZWN0WzNdLTEKKwkJc2VsZi5fbGlzdCA9IExpc3QuTE5ldyhyZWN0LCAoMCwgMCwgc2VsZi5fY29scywgMCksICgwLCAwKSwgc2VsZi5MREVGX0lELCBzZWxmLl9wYXJlbnR3aW5kb3cud2lkLAorCQkJCQkwLCAxLCAwLCAxKQorCQlpZiBzZWxmLmRyYXdpbmdtb2RlOgorCQkJc2VsZi5fbGlzdC5MU2V0RHJhd2luZ01vZGUoMCkKKwkJc2VsZi5fbGlzdC5zZWxGbGFncyA9IHNlbGYuX2ZsYWdzCisJCXNlbGYuc2V0aXRlbXMoc2VsZi5pdGVtcykKKwkJaWYgaGFzYXR0cihzZWxmLCAiX3NlbCIpOgorCQkJc2VsZi5zZXRzZWxlY3Rpb24oc2VsZi5fc2VsKQorCQkJZGVsIHNlbGYuX3NlbAorCQorCWRlZiBhZGp1c3Qoc2VsZiwgb2xkYm91bmRzKToKKwkJc2VsZi5TZXRQb3J0KCkKKwkJaWYgc2VsZi5fc2VsZWN0ZWQ6CisJCQlXaW4uSW52YWxSZWN0KFFkLkluc2V0UmVjdChvbGRib3VuZHMsIC0zLCAtMykpCisJCQlXaW4uSW52YWxSZWN0KFFkLkluc2V0UmVjdChzZWxmLl9ib3VuZHMsIC0zLCAtMykpCisJCWVsc2U6CisJCQlXaW4uSW52YWxSZWN0KG9sZGJvdW5kcykKKwkJCVdpbi5JbnZhbFJlY3Qoc2VsZi5fYm91bmRzKQorCQlpZiBvbGRib3VuZHNbOjJdID09IHNlbGYuX2JvdW5kc1s6Ml06CisJCQkjIGxpc3Qgc3RpbGwgaGFzIHRoZSBzYW1lIHVwcGVyL2xlZnQgY29vcmRpbmF0ZXMsIHVzZSBMU2l6ZQorCQkJbCwgdCwgciwgYiA9IHNlbGYuX2JvdW5kcworCQkJd2lkdGggPSByIC0gbCAtIDE3CisJCQloZWlnaHQgPSBiIC0gdCAtIDIKKwkJCXNlbGYuX2xpc3QuTFNpemUod2lkdGgsIGhlaWdodCkKKwkJCSMgbm93ICp3aHkqIGRlb3NuJ3QgdGhlIGxpc3QgbWFuYWdlciByZWNhbGMgdGhlIGNlbGxyZWN0Pz8/CisJCQlsLCB0LCByLCBiID0gc2VsZi5fbGlzdC5MUmVjdCgoMCwwKSkKKwkJCWNlbGxoZWlnaHQgPSBiIC0gdAorCQkJc2VsZi5fbGlzdC5MQ2VsbFNpemUoKHdpZHRoLCBjZWxsaGVpZ2h0KSkKKwkJZWxzZToKKwkJCSMgb2ggd2VsbCwgc2ljZSB0aGUgbGlzdCBtYW5hZ2VyIGRvZXNuJ3QgaGF2ZSBhIExNb3ZlIGNhbGwsCisJCQkjIHdlIGhhdmUgdG8gbWFrZSB0aGUgbGlzdCBhbGwgb3ZlciBhZ2Fpbi4uLgorCQkJc2VsID0gc2VsZi5nZXRzZWxlY3Rpb24oKQorCQkJdG9wY2VsbCA9IHNlbGYuZ2V0dG9wY2VsbCgpCisJCQlzZWxmLl9saXN0ID0gTm9uZQorCQkJc2VsZi5zZXRkcmF3aW5nbW9kZSgwKQorCQkJc2VsZi5jcmVhdGVsaXN0KCkKKwkJCXNlbGYuc2V0c2VsZWN0aW9uKHNlbCkKKwkJCXNlbGYuc2V0dG9wY2VsbCh0b3BjZWxsKQorCQkJc2VsZi5zZXRkcmF3aW5nbW9kZSgxKQorCQorCWRlZiBjbG9zZShzZWxmKToKKwkJc2VsZi5fbGlzdCA9IE5vbmUKKwkJc2VsZi5fY2FsbGJhY2sgPSBOb25lCisJCXNlbGYuaXRlbXNbOl0gPSBbXQorCQlXYmFzZS5TZWxlY3RhYmxlV2lkZ2V0LmNsb3NlKHNlbGYpCisJCisJZGVmIHNldChzZWxmLCBpdGVtcyk6CisJCXNlbGYuc2V0aXRlbXMoaXRlbXMpCisJCisJZGVmIHNldGl0ZW1zKHNlbGYsIGl0ZW1zKToKKwkJc2VsZi5pdGVtcyA9IGl0ZW1zCisJCXRoZV9saXN0ID0gc2VsZi5fbGlzdAorCQlpZiBub3Qgc2VsZi5fcGFyZW50IG9yIG5vdCBzZWxmLl9saXN0OgorCQkJcmV0dXJuCisJCXNlbGYuc2V0ZHJhd2luZ21vZGUoMCkKKwkJdG9wY2VsbCA9IHNlbGYuZ2V0dG9wY2VsbCgpCisJCXRoZV9saXN0LkxEZWxSb3coMCwgMSkKKwkJdGhlX2xpc3QuTEFkZFJvdyhsZW4oc2VsZi5pdGVtcyksIDApCisJCXNlbGZfaXRlbXJlcHIgPSBzZWxmLml0ZW1yZXByCisJCXNldF9jZWxsID0gdGhlX2xpc3QuTFNldENlbGwKKwkJZm9yIGkgaW4gcmFuZ2UobGVuKGl0ZW1zKSk6CisJCQlzZXRfY2VsbChzZWxmX2l0ZW1yZXByKGl0ZW1zW2ldKSwgKDAsIGkpKQorCQlzZWxmLnNldHRvcGNlbGwodG9wY2VsbCkKKwkJc2VsZi5zZXRkcmF3aW5nbW9kZSgxKQorCQorCWRlZiBjbGljayhzZWxmLCBwb2ludCwgbW9kaWZpZXJzKToKKwkJaWYgbm90IHNlbGYuX2VuYWJsZWQ6CisJCQlyZXR1cm4KKwkJaXNkb3VibGVjbGljayA9IHNlbGYuX2xpc3QuTENsaWNrKHBvaW50LCBtb2RpZmllcnMpCisJCWlmIHNlbGYuX2NhbGxiYWNrOgorCQkJV2Jhc2UuQ2FsbGJhY2tDYWxsKHNlbGYuX2NhbGxiYWNrLCAwLCBpc2RvdWJsZWNsaWNrKQorCQlyZXR1cm4gMQorCQorCWRlZiBrZXkoc2VsZiwgY2hhciwgZXZlbnQpOgorCQkod2hhdCwgbWVzc2FnZSwgd2hlbiwgd2hlcmUsIG1vZGlmaWVycykgPSBldmVudAorCQlzZWwgPSBzZWxmLmdldHNlbGVjdGlvbigpCisJCW5ld3NlbGVjdGlvbiA9IFtdCisJCWlmIGNoYXIgPT0gdXBhcnJvd2tleToKKwkJCWlmIGxlbihzZWwpID49IDEgYW5kIG1pbihzZWwpID4gMDoKKwkJCQluZXdzZWxlY3Rpb24gPSBbbWluKHNlbCkgLSAxXQorCQkJZWxzZToKKwkJCQluZXdzZWxlY3Rpb24gPSBbMF0KKwkJZWxpZiBjaGFyID09IGRvd25hcnJvd2tleToKKwkJCWlmIGxlbihzZWwpID49IDEgYW5kIG1heChzZWwpIDwgKGxlbihzZWxmLml0ZW1zKSAtIDEpOgorCQkJCQluZXdzZWxlY3Rpb24gPSBbbWF4KHNlbCkgKyAxXQorCQkJZWxzZToKKwkJCQluZXdzZWxlY3Rpb24gPSBbbGVuKHNlbGYuaXRlbXMpIC0gMV0KKwkJZWxzZToKKwkJCW1vZGlmaWVycyA9IDAKKwkJCWlmIChzZWxmLmxhc3R0aW1lICsgc2VsZi50aW1lbGltaXQpIDwgRXZ0LlRpY2tDb3VudCgpOgorCQkJCXNlbGYubGFzdHR5cGluZyA9ICIiCisJCQlzZWxmLmxhc3R0eXBpbmcgPSBzZWxmLmxhc3R0eXBpbmcgKyBzdHJpbmcubG93ZXIoY2hhcikKKwkJCXNlbGYubGFzdHRpbWUgPSBFdnQuVGlja0NvdW50KCkKKwkJCWkgPSBzZWxmLmZpbmRtYXRjaChzZWxmLmxhc3R0eXBpbmcpCisJCQluZXdzZWxlY3Rpb24gPSBbaV0KKwkJaWYgbW9kaWZpZXJzICYgRXZlbnRzLnNoaWZ0S2V5OgorCQkJbmV3c2VsZWN0aW9uID0gbmV3c2VsZWN0aW9uICsgc2VsCisJCXNlbGYuc2V0c2VsZWN0aW9uKG5ld3NlbGVjdGlvbikKKwkJc2VsZi5fbGlzdC5MQXV0b1Njcm9sbCgpCisJCXNlbGYuY2xpY2soKC0xLCAtMSksIDApCisJCisJZGVmIGZpbmRtYXRjaChzZWxmLCB0YWcpOgorCQlsb3dlciA9IHN0cmluZy5sb3dlcgorCQlpdGVtcyA9IHNlbGYuaXRlbXMKKwkJdGFnbGVuID0gbGVuKHRhZykKKwkJbWF0Y2ggPSAnXDM3NycgKiAxMDAKKwkJbWF0Y2hfaSA9IC0xCisJCWZvciBpIGluIHJhbmdlKGxlbihpdGVtcykpOgorCQkJaXRlbSA9IGxvd2VyKHN0cihpdGVtc1tpXSkpCisJCQlpZiB0YWcgPD0gaXRlbSA8IG1hdGNoOgorCQkJCW1hdGNoID0gaXRlbQorCQkJCW1hdGNoX2kgPSBpCisJCWlmIG1hdGNoX2kgPj0gMDoKKwkJCXJldHVybiBtYXRjaF9pCisJCWVsc2U6CisJCQlyZXR1cm4gbGVuKGl0ZW1zKSAtIDEKKwkKKwlkZWYgZG9tZW51X2NvcHkoc2VsZiwgKmFyZ3MpOgorCQlzZWwgPSBzZWxmLmdldHNlbGVjdGlvbigpCisJCXNlbGl0ZW1zID0gW10KKwkJZm9yIGkgaW4gc2VsOgorCQkJc2VsaXRlbXMuYXBwZW5kKHN0cihzZWxmLml0ZW1zW2ldKSkKKwkJdGV4dCA9IHN0cmluZy5qb2luKHNlbGl0ZW1zLCAnXHInKQorCQlpZiB0ZXh0OgorCQkJU2NyYXAuWmVyb1NjcmFwKCkKKwkJCVNjcmFwLlB1dFNjcmFwKCdURVhUJywgdGV4dCkKKwkKKwlkZWYgY2FuX2NvcHkoc2VsZiwgKmFyZ3MpOgorCQlyZXR1cm4gbGVuKHNlbGYuZ2V0c2VsZWN0aW9uKCkpIDw+IDAKKwkKKwlkZWYgZG9tZW51X3NlbGVjdGFsbChzZWxmLCAqYXJncyk6CisJCXNlbGYuc2VsZWN0YWxsKCkKKwkKKwlkZWYgc2VsZWN0YWxsKHNlbGYpOgorCQlzZWxmLnNldHNlbGVjdGlvbihyYW5nZShsZW4oc2VsZi5pdGVtcykpKQorCQlzZWxmLl9saXN0LkxBdXRvU2Nyb2xsKCkKKwkJc2VsZi5jbGljaygoLTEsIC0xKSwgMCkKKwkKKwlkZWYgZ2V0c2VsZWN0aW9uKHNlbGYpOgorCQlpZiBub3Qgc2VsZi5fcGFyZW50IG9yIG5vdCBzZWxmLl9saXN0OgorCQkJaWYgaGFzYXR0cihzZWxmLCAiX3NlbCIpOgorCQkJCXJldHVybiBzZWxmLl9zZWwKKwkJCXJldHVybiBbXQorCQlpdGVtcyA9IFtdCisJCXBvaW50ID0gKDAsMCkKKwkJd2hpbGUgMToKKwkJCW9rLCBwb2ludCA9IHNlbGYuX2xpc3QuTEdldFNlbGVjdCgxLCBwb2ludCkKKwkJCWlmIG5vdCBvazoKKwkJCQlicmVhaworCQkJaXRlbXMuYXBwZW5kKHBvaW50WzFdKQorCQkJcG9pbnQgPSBwb2ludFswXSwgcG9pbnRbMV0rMQorCQlyZXR1cm4gaXRlbXMKKwkKKwlkZWYgc2V0c2VsZWN0aW9uKHNlbGYsIHNlbGVjdGlvbik6CisJCWlmIG5vdCBzZWxmLl9wYXJlbnQgb3Igbm90IHNlbGYuX2xpc3Q6CisJCQlzZWxmLl9zZWwgPSBzZWxlY3Rpb24KKwkJCXJldHVybgorCQlzZXRfc2VsID0gc2VsZi5fbGlzdC5MU2V0U2VsZWN0CisJCWZvciBpIGluIHJhbmdlKGxlbihzZWxmLml0ZW1zKSk6CisJCQlpZiBpIGluIHNlbGVjdGlvbjoKKwkJCQlzZXRfc2VsKDEsICgwLCBpKSkKKwkJCWVsc2U6CisJCQkJc2V0X3NlbCgwLCAoMCwgaSkpCisJCXNlbGYuX2xpc3QuTEF1dG9TY3JvbGwoKQorCQorCWRlZiBnZXRzZWxlY3RlZG9iamVjdHMoc2VsZik6CisJCXNlbCA9IHNlbGYuZ2V0c2VsZWN0aW9uKCkKKwkJb2JqZWN0cyA9IFtdCisJCWZvciBpIGluIHNlbDoKKwkJCW9iamVjdHMuYXBwZW5kKHNlbGYuaXRlbXNbaV0pCisJCXJldHVybiBvYmplY3RzCisJCisJZGVmIHNldHNlbGVjdGVkb2JqZWN0cyhzZWxmLCBvYmplY3RzKToKKwkJc2VsID0gW10KKwkJZm9yIG8gaW4gb2JqZWN0czoKKwkJCXRyeToKKwkJCQlzZWwuYXBwZW5kKHNlbGYuaXRlbXMuaW5kZXgobykpCisJCQlleGNlcHQ6CisJCQkJcGFzcworCQlzZWxmLnNldHNlbGVjdGlvbihzZWwpCisJCisJZGVmIGdldHRvcGNlbGwoc2VsZik6CisJCWwsIHQsIHIsIGIgPSBzZWxmLl9ib3VuZHMKKwkJdCA9IHQgKyAxCisJCWNsLCBjdCwgY3IsIGNiID0gc2VsZi5fbGlzdC5MUmVjdCgoMCwgMCkpCisJCWNlbGxoZWlnaHQgPSBjYiAtIGN0CisJCXJldHVybiAodCAtIGN0KSAvIGNlbGxoZWlnaHQKKwkKKwlkZWYgc2V0dG9wY2VsbChzZWxmLCB0b3BjZWxsKToKKwkJdG9wID0gc2VsZi5nZXR0b3BjZWxsKCkKKwkJZGlmZiA9IHRvcGNlbGwgLSB0b3AKKwkJc2VsZi5fbGlzdC5MU2Nyb2xsKDAsIGRpZmYpCisJCisJZGVmIGRyYXcoc2VsZiwgdmlzUmduID0gTm9uZSk6CisJCWlmIHNlbGYuX3Zpc2libGU6CisJCQlpZiBub3QgdmlzUmduOgorCQkJCXZpc1JnbiA9IHNlbGYuX3BhcmVudHdpbmRvdy53aWQuR2V0V2luZG93UG9ydCgpLnZpc1JnbgorCQkJc2VsZi5fbGlzdC5MVXBkYXRlKHZpc1JnbikKKwkJCVFkLkZyYW1lUmVjdChzZWxmLl9ib3VuZHMpCisJCQlpZiBzZWxmLl9zZWxlY3RlZCBhbmQgc2VsZi5fYWN0aXZhdGVkOgorCQkJCXNlbGYuZHJhd3NlbGZyYW1lKDEpCisJCisJZGVmIGFkanVzdChzZWxmLCBvbGRib3VuZHMpOgorCQlzZWxmLlNldFBvcnQoKQorCQlpZiBzZWxmLl9zZWxlY3RlZDoKKwkJCVdpbi5JbnZhbFJlY3QoUWQuSW5zZXRSZWN0KG9sZGJvdW5kcywgLTMsIC0zKSkKKwkJCVdpbi5JbnZhbFJlY3QoUWQuSW5zZXRSZWN0KHNlbGYuX2JvdW5kcywgLTMsIC0zKSkKKwkJZWxzZToKKwkJCVdpbi5JbnZhbFJlY3Qob2xkYm91bmRzKQorCQkJV2luLkludmFsUmVjdChzZWxmLl9ib3VuZHMpCisJCWlmIG9sZGJvdW5kc1s6Ml0gPT0gc2VsZi5fYm91bmRzWzoyXToKKwkJCSMgbGlzdCBzdGlsbCBoYXMgdGhlIHNhbWUgdXBwZXIvbGVmdCBjb29yZGluYXRlcywgdXNlIExTaXplCisJCQlsLCB0LCByLCBiID0gc2VsZi5fYm91bmRzCisJCQl3aWR0aCA9IHIgLSBsIC0gMTcKKwkJCWhlaWdodCA9IGIgLSB0IC0gMgorCQkJc2VsZi5fbGlzdC5MU2l6ZSh3aWR0aCwgaGVpZ2h0KQorCQkJIyBub3cgKndoeSogZGVvc24ndCB0aGUgbGlzdCBtYW5hZ2VyIHJlY2FsYyB0aGUgY2VsbHJlY3Q/Pz8KKwkJCWwsIHQsIHIsIGIgPSBzZWxmLl9saXN0LkxSZWN0KCgwLDApKQorCQkJY2VsbGhlaWdodCA9IGIgLSB0CisJCQlzZWxmLl9saXN0LkxDZWxsU2l6ZSgod2lkdGgsIGNlbGxoZWlnaHQpKQorCQllbHNlOgorCQkJIyBvaCB3ZWxsLCBzaWNlIHRoZSBsaXN0IG1hbmFnZXIgZG9lc24ndCBoYXZlIGEgTE1vdmUgY2FsbCwKKwkJCSMgd2UgaGF2ZSB0byBtYWtlIHRoZSBsaXN0IGFsbCBvdmVyIGFnYWluLi4uCisJCQlzZWwgPSBzZWxmLmdldHNlbGVjdGlvbigpCisJCQl0b3BjZWxsID0gc2VsZi5nZXR0b3BjZWxsKCkKKwkJCXNlbGYuX2xpc3QgPSBOb25lCisJCQlzZWxmLnNldGRyYXdpbmdtb2RlKDApCisJCQlzZWxmLmNyZWF0ZWxpc3QoKQorCQkJc2VsZi5zZXRzZWxlY3Rpb24oc2VsKQorCQkJc2VsZi5zZXR0b3BjZWxsKHRvcGNlbGwpCisJCQlzZWxmLnNldGRyYXdpbmdtb2RlKDEpCisJCisJZGVmIHNlbGVjdChzZWxmLCBvbm9mZiwgaXNjbGljayA9IDApOgorCQlpZiBXYmFzZS5TZWxlY3RhYmxlV2lkZ2V0LnNlbGVjdChzZWxmLCBvbm9mZik6CisJCQlyZXR1cm4KKwkJc2VsZi5TZXRQb3J0KCkKKwkJc2VsZi5kcmF3c2VsZnJhbWUob25vZmYpCisJCisJZGVmIGFjdGl2YXRlKHNlbGYsIG9ub2ZmKToKKwkJc2VsZi5fYWN0aXZhdGVkID0gb25vZmYKKwkJaWYgc2VsZi5fdmlzaWJsZToKKwkJCXNlbGYuX2xpc3QuTEFjdGl2YXRlKG9ub2ZmKQorCQkJaWYgc2VsZi5fc2VsZWN0ZWQ6CisJCQkJc2VsZi5kcmF3c2VsZnJhbWUob25vZmYpCisJCisJZGVmIGdldChzZWxmKToKKwkJcmV0dXJuIHNlbGYuaXRlbXMKKwkKKwlkZWYgaXRlbXJlcHIoc2VsZiwgaXRlbSk6CisJCXJldHVybiBzdHIoaXRlbSlbOjI1NV0KKwkKKwlkZWYgX19nZXRpdGVtX18oc2VsZiwgaW5kZXgpOgorCQlyZXR1cm4gc2VsZi5pdGVtc1tpbmRleF0KKwkKKwlkZWYgX19zZXRpdGVtX18oc2VsZiwgaW5kZXgsIGl0ZW0pOgorCQlpZiBzZWxmLl9wYXJlbnQgYW5kIHNlbGYuX2xpc3Q6CisJCQlzZWxmLl9saXN0LkxTZXRDZWxsKHNlbGYuaXRlbXJlcHIoaXRlbSksICgwLCBpbmRleCkpCisJCXNlbGYuaXRlbXNbaW5kZXhdID0gaXRlbQorCQorCWRlZiBfX2RlbGl0ZW1fXyhzZWxmLCBpbmRleCk6CisJCWlmIHNlbGYuX3BhcmVudCBhbmQgc2VsZi5fbGlzdDoKKwkJCXNlbGYuX2xpc3QuTERlbFJvdygxLCBpbmRleCkKKwkJZGVsIHNlbGYuaXRlbXNbaW5kZXhdCisJCisJZGVmIF9fZ2V0c2xpY2VfXyhzZWxmLCBhLCBiKToKKwkJcmV0dXJuIHNlbGYuaXRlbXNbYTpiXQorCQorCWRlZiBfX2RlbHNsaWNlX18oc2VsZiwgYSwgYik6CisJCWlmIGItYToKKwkJCWlmIHNlbGYuX3BhcmVudCBhbmQgc2VsZi5fbGlzdDoKKwkJCQlzZWxmLl9saXN0LkxEZWxSb3coYi1hLCBhKQorCQkJZGVsIHNlbGYuaXRlbXNbYTpiXQorCQorCWRlZiBfX3NldHNsaWNlX18oc2VsZiwgYSwgYiwgaXRlbXMpOgorCQlpZiBzZWxmLl9wYXJlbnQgYW5kIHNlbGYuX2xpc3Q6CisJCQlsID0gbGVuKGl0ZW1zKQorCQkJdGhlX2xpc3QgPSBzZWxmLl9saXN0CisJCQlzZWxmLnNldGRyYXdpbmdtb2RlKDApCisJCQlpZiBiLWE6CisJCQkJaWYgYiA+IGxlbihzZWxmLml0ZW1zKToKKwkJCQkJIyBmaXggZm9yIG5ldyAxLjUgImZlYXR1cmUiIHdoZXJlIGIgaXMgc3lzLm1heGludCBpbnN0ZWFkIG9mIGxlbihzZWxmKS4uLgorCQkJCQkjIExEZWxSb3cgZG9lc24ndCBsaWtlIG1heGludC4KKwkJCQkJYiA9IGxlbihzZWxmLml0ZW1zKQorCQkJCXRoZV9saXN0LkxEZWxSb3coYi1hLCBhKQorCQkJdGhlX2xpc3QuTEFkZFJvdyhsLCBhKQorCQkJc2VsZl9pdGVtcmVwciA9IHNlbGYuaXRlbXJlcHIKKwkJCXNldF9jZWxsID0gdGhlX2xpc3QuTFNldENlbGwKKwkJCWZvciBpIGluIHJhbmdlKGxlbihpdGVtcykpOgorCQkJCXNldF9jZWxsKHNlbGZfaXRlbXJlcHIoaXRlbXNbaV0pLCAoMCwgaSArIGEpKQorCQkJc2VsZi5pdGVtc1thOmJdID0gaXRlbXMKKwkJCXNlbGYuc2V0ZHJhd2luZ21vZGUoMSkKKwkJZWxzZToKKwkJCXNlbGYuaXRlbXNbYTpiXSA9IGl0ZW1zCisJCisJZGVmIF9fbGVuX18oc2VsZik6CisJCXJldHVybiBsZW4oc2VsZi5pdGVtcykKKwkKKwlkZWYgYXBwZW5kKHNlbGYsIGl0ZW0pOgorCQlpZiBzZWxmLl9wYXJlbnQgYW5kIHNlbGYuX2xpc3Q6CisJCQlpbmRleCA9IGxlbihzZWxmLml0ZW1zKQorCQkJc2VsZi5fbGlzdC5MQWRkUm93KDEsIGluZGV4KQorCQkJc2VsZi5fbGlzdC5MU2V0Q2VsbChzZWxmLml0ZW1yZXByKGl0ZW0pLCAoMCwgaW5kZXgpKQorCQlzZWxmLml0ZW1zLmFwcGVuZChpdGVtKQorCQorCWRlZiByZW1vdmUoc2VsZiwgaXRlbSk6CisJCWluZGV4ID0gc2VsZi5pdGVtcy5pbmRleChpdGVtKQorCQlzZWxmLl9fZGVsaXRlbV9fKGluZGV4KQorCQorCWRlZiBpbmRleChzZWxmLCBpdGVtKToKKwkJcmV0dXJuIHNlbGYuaXRlbXMuaW5kZXgoaXRlbSkKKwkKKwlkZWYgaW5zZXJ0KHNlbGYsIGluZGV4LCBpdGVtKToKKwkJaWYgaW5kZXggPCAwOgorCQkJaW5kZXggPSAwCisJCWlmIHNlbGYuX3BhcmVudCBhbmQgc2VsZi5fbGlzdDoKKwkJCXNlbGYuX2xpc3QuTEFkZFJvdygxLCBpbmRleCkKKwkJCXNlbGYuX2xpc3QuTFNldENlbGwoc2VsZi5pdGVtcmVwcihpdGVtKSwgKDAsIGluZGV4KSkKKwkJc2VsZi5pdGVtcy5pbnNlcnQoaW5kZXgsIGl0ZW0pCisJCisJZGVmIHNldGRyYXdpbmdtb2RlKHNlbGYsIG9ub2ZmKToKKwkJaWYgb25vZmY6CisJCQlzZWxmLmRyYXdpbmdtb2RlID0gc2VsZi5kcmF3aW5nbW9kZSAtIDEKKwkJCWlmIHNlbGYuZHJhd2luZ21vZGUgPT0gMCBhbmQgc2VsZi5fbGlzdCBpcyBub3QgTm9uZToKKwkJCQlzZWxmLl9saXN0LkxTZXREcmF3aW5nTW9kZSgxKQorCQkJCWlmIHNlbGYuX3Zpc2libGU6CisJCQkJCWJvdW5kcyA9IGwsIHQsIHIsIGIgPSBRZC5JbnNldFJlY3Qoc2VsZi5fYm91bmRzLCAxLCAxKQorCQkJCQljbCwgY3QsIGNyLCBjYiA9IHNlbGYuX2xpc3QuTFJlY3QoKDAsIGxlbihzZWxmLml0ZW1zKS0xKSkKKwkJCQkJaWYgY2IgPCBiOgorCQkJCQkJc2VsZi5TZXRQb3J0KCkKKwkJCQkJCVFkLkVyYXNlUmVjdCgobCwgY2IsIGNyLCBiKSkKKwkJCQkJc2VsZi5fbGlzdC5MVXBkYXRlKHNlbGYuX3BhcmVudHdpbmRvdy53aWQuR2V0V2luZG93UG9ydCgpLnZpc1JnbikKKwkJCQkJV2luLlZhbGlkUmVjdChib3VuZHMpCisJCWVsc2U6CisJCQlpZiBzZWxmLmRyYXdpbmdtb2RlID09IDAgYW5kIHNlbGYuX2xpc3QgaXMgbm90IE5vbmU6CisJCQkJc2VsZi5fbGlzdC5MU2V0RHJhd2luZ01vZGUoMCkKKwkJCXNlbGYuZHJhd2luZ21vZGUgPSBzZWxmLmRyYXdpbmdtb2RlICsgMQorCisKK2NsYXNzIE11bHRpTGlzdChMaXN0KToKKwkKKwlkZWYgc2V0aXRlbXMoc2VsZiwgaXRlbXMpOgorCQlzZWxmLml0ZW1zID0gaXRlbXMKKwkJaWYgbm90IHNlbGYuX3BhcmVudCBvciBub3Qgc2VsZi5fbGlzdDoKKwkJCXJldHVybgorCQlzZWxmLl9saXN0LkxEZWxSb3coMCwgMSkKKwkJc2VsZi5zZXRkcmF3aW5nbW9kZSgwKQorCQlzZWxmLl9saXN0LkxBZGRSb3cobGVuKHNlbGYuaXRlbXMpLCAwKQorCQlzZWxmX2l0ZW1yZXByID0gc2VsZi5pdGVtcmVwcgorCQlzZXRfY2VsbCA9IHNlbGYuX2xpc3QuTFNldENlbGwKKwkJZm9yIGkgaW4gcmFuZ2UobGVuKGl0ZW1zKSk6CisJCQlyb3cgPSBpdGVtc1tpXQorCQkJZm9yIGogaW4gcmFuZ2UobGVuKHJvdykpOgorCQkJCWl0ZW0gPSByb3dbal0KKwkJCQlzZXRfY2VsbChzZWxmX2l0ZW1yZXByKGl0ZW0pLCAoaiwgaSkpCisJCXNlbGYuc2V0ZHJhd2luZ21vZGUoMSkKKwkKKwlkZWYgZ2V0c2VsZWN0aW9uKHNlbGYpOgorCQlpZiBub3Qgc2VsZi5fcGFyZW50IG9yIG5vdCBzZWxmLl9saXN0OgorCQkJaWYgaGFzYXR0cihzZWxmLCAiX3NlbCIpOgorCQkJCXJldHVybiBzZWxmLl9zZWwKKwkJCXJldHVybiBbXQorCQlpdGVtcyA9IFtdCisJCXBvaW50ID0gKDAsMCkKKwkJd2hpbGUgMToKKwkJCW9rLCBwb2ludCA9IHNlbGYuX2xpc3QuTEdldFNlbGVjdCgxLCBwb2ludCkKKwkJCWlmIG5vdCBvazoKKwkJCQlicmVhaworCQkJaXRlbXMuYXBwZW5kKHBvaW50WzFdKQorCQkJcG9pbnQgPSBwb2ludFswXSwgcG9pbnRbMV0rMQorCQlyZXR1cm4gaXRlbXMKKwkKKwlkZWYgc2V0c2VsZWN0aW9uKHNlbGYsIHNlbGVjdGlvbik6CisJCWlmIG5vdCBzZWxmLl9wYXJlbnQgb3Igbm90IHNlbGYuX2xpc3Q6CisJCQlzZWxmLl9zZWwgPSBzZWxlY3Rpb24KKwkJCXJldHVybgorCQlzZXRfc2VsID0gc2VsZi5fbGlzdC5MU2V0U2VsZWN0CisJCWZvciBpIGluIHJhbmdlKGxlbihzZWxmLml0ZW1zKSk6CisJCQlpZiBpIGluIHNlbGVjdGlvbjoKKwkJCQlzZXRfc2VsKDEsICgwLCBpKSkKKwkJCWVsc2U6CisJCQkJc2V0X3NlbCgwLCAoMCwgaSkpCisJCSNzZWxmLl9saXN0LkxBdXRvU2Nyb2xsKCkKKwpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1dtZW51cy5weSBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XbWVudXMucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMzUwZTAzNgotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XbWVudXMucHkKQEAgLTAsMCArMSwxODIgQEAKK2ltcG9ydCBGcmFtZVdvcmsKK2ltcG9ydCBRZAoraW1wb3J0IFdiYXNlCitmcm9tIHR5cGVzIGltcG9ydCAqCitpbXBvcnQgV0ZyYW1lV29ya1BhdGNoCisKK19hcnJvd3JpZ2h0ID0gUWQuR2V0UGljdHVyZSg0NzIpCitfYXJyb3dkb3duID0gUWQuR2V0UGljdHVyZSg0NzMpCisJCisKKworY2xhc3MgUG9wdXBXaWRnZXQoV2Jhc2UuQ2xpY2thYmxlV2lkZ2V0KToKKwkKKwlkZWYgX19pbml0X18oc2VsZiwgcG9zc2l6ZSwgaXRlbXMgPSBbXSwgY2FsbGJhY2sgPSBOb25lKToKKwkJV2Jhc2UuV2lkZ2V0Ll9faW5pdF9fKHNlbGYsIHBvc3NpemUpCisJCXNlbGYuX2l0ZW1zID0gaXRlbXMKKwkJc2VsZi5faXRlbXNkaWN0ID0ge30KKwkJc2VsZi5fY2FsbGJhY2sgPSBjYWxsYmFjaworCQlzZWxmLl9lbmFibGVkID0gMQorCQorCWRlZiBjbG9zZShzZWxmKToKKwkJV2Jhc2UuV2lkZ2V0LmNsb3NlKHNlbGYpCisJCXNlbGYuX2l0ZW1zID0gTm9uZQorCQlzZWxmLl9pdGVtc2RpY3QgPSB7fQorCQorCWRlZiBkcmF3KHNlbGYsIHZpc1JnbiA9IE5vbmUpOgorCQlpZiBzZWxmLl92aXNpYmxlOgorCQkJUWQuRnJhbWVSZWN0KHNlbGYuX2JvdW5kcykKKwkJCWwsIHQsIHIsIGIgPSBzZWxmLl9ib3VuZHMKKwkJCWwgPSBsICsgMgorCQkJdCA9IHQgKyAzCisJCQlwaWN0ZnJhbWUgPSAobCwgdCwgbCArIDEwLCB0ICsgMTApCisJCQlRZC5EcmF3UGljdHVyZShfYXJyb3dyaWdodCwgcGljdGZyYW1lKQorCQorCWRlZiBjbGljayhzZWxmLCBwb2ludCwgbW9kaWZpZXJzKToKKwkJaWYgbm90IHNlbGYuX2VuYWJsZWQ6CisJCQlyZXR1cm4KKwkJc2VsZi5tZW51ID0gRnJhbWVXb3JrLk1lbnUoc2VsZi5fcGFyZW50d2luZG93LnBhcmVudC5tZW51YmFyLCAnRm9vJywgLTEpCisJCXNlbGYuX2FkZGl0ZW1zKHNlbGYuX2l0ZW1zLCBzZWxmLm1lbnUpCisJCQorCQlzZWxmLlNldFBvcnQoKQorCQlsLCB0LCByLCBiID0gc2VsZi5fYm91bmRzCisJCWwsIHQgPSBRZC5Mb2NhbFRvR2xvYmFsKChsKzEsIHQrMSkpCisJCVdiYXNlLlNldEN1cnNvcigiYXJyb3ciKQorCQlyZXBseSA9IHNlbGYubWVudS5tZW51LlBvcFVwTWVudVNlbGVjdCh0LCBsLCAxKQorCQlpZiByZXBseToKKwkJCWlkID0gKHJlcGx5ICYgMHhmZmZmMDAwMCkgPj4gMTYKKwkJCWl0ZW0gPSByZXBseSAmIDB4ZmZmZgorCQkJc2VsZi5fbWVudV9jYWxsYmFjayhpZCwgaXRlbSkKKwkJc2VsZi5fZW1wdHltZW51KCkKKwkKKwlkZWYgc2V0KHNlbGYsIGl0ZW1zKToKKwkJc2VsZi5faXRlbXMgPSBpdGVtcworCQorCWRlZiBfYWRkaXRlbXMoc2VsZiwgaXRlbXMsIG1lbnUpOgorCQlmcm9tIEZyYW1lV29yayBpbXBvcnQgU3ViTWVudSwgTWVudUl0ZW0KKwkJbWVudV9pZCA9IG1lbnUuaWQKKwkJZm9yIGl0ZW0gaW4gaXRlbXM6CisJCQlpZiBpdGVtID09ICItIjoKKwkJCQltZW51LmFkZHNlcGFyYXRvcigpCisJCQkJY29udGludWUKKwkJCWVsaWYgdHlwZShpdGVtKSA9PSBMaXN0VHlwZToKKwkJCQlzdWJtZW51ID0gU3ViTWVudShtZW51LCBpdGVtWzBdKQorCQkJCXNlbGYuX2FkZGl0ZW1zKGl0ZW1bMTpdLCBzdWJtZW51KQorCQkJCWNvbnRpbnVlCisJCQllbGlmIHR5cGUoaXRlbSkgPT0gU3RyaW5nVHlwZToKKwkJCQltZW51aXRlbXRleHQgPSBvYmplY3QgPSBpdGVtCisJCQllbGlmIHR5cGUoaXRlbSkgPT0gVHVwbGVUeXBlIGFuZCBsZW4oaXRlbSkgPT0gMjoKKwkJCQltZW51aXRlbXRleHQsIG9iamVjdCA9IGl0ZW0KKwkJCWVsc2U6CisJCQkJcmFpc2UgV2lkZ2V0c0Vycm9yLCAiaWxsZWdhbCBpdGVtbGlzdCBmb3IgcG9wdXAgbWVudSIKKwkJCQorCQkJaWYgbWVudWl0ZW10ZXh0WzoxXSA9PSAnXDAnOgorCQkJCWNoZWNrID0gb3JkKG1lbnVpdGVtdGV4dFsxXSkKKwkJCQltZW51aXRlbXRleHQgPSBtZW51aXRlbXRleHRbMjpdCisJCQllbHNlOgorCQkJCWNoZWNrID0gMAorCQkJbWVudWl0ZW0gPSBNZW51SXRlbShtZW51LCBtZW51aXRlbXRleHQsIE5vbmUsIE5vbmUpCisJCQlpZiBjaGVjazoKKwkJCQltZW51aXRlbS5jaGVjaygxKQorCQkJc2VsZi5faXRlbXNkaWN0WyhtZW51X2lkLCBtZW51aXRlbS5pdGVtKV0gPSBvYmplY3QKKwkKKwlkZWYgX2VtcHR5bWVudShzZWxmKToKKwkJbWVudXMgPSBzZWxmLl9wYXJlbnR3aW5kb3cucGFyZW50Lm1lbnViYXIubWVudXMKKwkJZm9yIGlkLCBpdGVtIGluIHNlbGYuX2l0ZW1zZGljdC5rZXlzKCk6CisJCQlpZiBtZW51cy5oYXNfa2V5KGlkKToKKwkJCQlzZWxmLm1lbnUgPSBtZW51c1tpZF0KKwkJCQlzZWxmLm1lbnUuZGVsZXRlKCkKKwkJc2VsZi5faXRlbXNkaWN0ID0ge30KKwkKKwlkZWYgX21lbnVfY2FsbGJhY2soc2VsZiwgaWQsIGl0ZW0pOgorCQl0aGluZyA9IHNlbGYuX2l0ZW1zZGljdFsoaWQsIGl0ZW0pXQorCQlpZiBjYWxsYWJsZSh0aGluZyk6CisJCQl0aGluZygpCisJCWVsaWYgc2VsZi5fY2FsbGJhY2s6CisJCQlXYmFzZS5DYWxsYmFja0NhbGwoc2VsZi5fY2FsbGJhY2ssIDAsIHRoaW5nKQorCisKK2NsYXNzIFBvcHVwTWVudShQb3B1cFdpZGdldCk6CisJCisJZGVmIG9wZW4oc2VsZik6CisJCXNlbGYuX2NhbGNib3VuZHMoKQorCQlzZWxmLm1lbnUgPSBXRnJhbWVXb3JrUGF0Y2guTWVudShzZWxmLl9wYXJlbnR3aW5kb3cucGFyZW50Lm1lbnViYXIsICdGb28nLCAtMSkKKwkJc2VsZi5fYWRkaXRlbXMoc2VsZi5faXRlbXMsIHNlbGYubWVudSkKKwkKKwlkZWYgY2xvc2Uoc2VsZik6CisJCXNlbGYuX2VtcHR5bWVudSgpCisJCVdiYXNlLldpZGdldC5jbG9zZShzZWxmKQorCQlzZWxmLl9pdGVtcyA9IE5vbmUKKwkJc2VsZi5faXRlbXNkaWN0ID0ge30KKwkJc2VsZi5tZW51ID0gTm9uZQorCQorCWRlZiBzZXQoc2VsZiwgaXRlbXMpOgorCQlpZiBzZWxmLl9pdGVtc2RpY3Q6CisJCQlzZWxmLl9lbXB0eW1lbnUoKQorCQlzZWxmLm1lbnUgPSBXRnJhbWVXb3JrUGF0Y2guTWVudShzZWxmLl9wYXJlbnR3aW5kb3cucGFyZW50Lm1lbnViYXIsICdGb28nLCAtMSkKKwkJc2VsZi5faXRlbXMgPSBpdGVtcworCQlzZWxmLl9hZGRpdGVtcyhzZWxmLl9pdGVtcywgc2VsZi5tZW51KQorCQorCWRlZiBjbGljayhzZWxmLCBwb2ludCwgbW9kaWZpZXJzKToKKwkJaWYgbm90IHNlbGYuX2VuYWJsZWQ6CisJCQlyZXR1cm4KKwkJc2VsZi5TZXRQb3J0KCkKKwkJbCwgdCwgciwgYiA9IHNlbGYuX2JvdW5kcworCQlsLCB0ID0gUWQuTG9jYWxUb0dsb2JhbCgobCsxLCB0KzEpKQorCQlXYmFzZS5TZXRDdXJzb3IoImFycm93IikKKwkJcmVwbHkgPSBzZWxmLm1lbnUubWVudS5Qb3BVcE1lbnVTZWxlY3QodCwgbCwgMSkKKwkJaWYgcmVwbHk6CisJCQlpZCA9IChyZXBseSAmIDB4ZmZmZjAwMDApID4+IDE2CisJCQlpdGVtID0gcmVwbHkgJiAweGZmZmYKKwkJCXNlbGYuX21lbnVfY2FsbGJhY2soaWQsIGl0ZW0pCisKKworY2xhc3MgRm9udE1lbnUoUG9wdXBNZW51KToKKwkKKwltZW51ID0gTm9uZQorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBwb3NzaXplLCBjYWxsYmFjayk6CisJCVBvcHVwTWVudS5fX2luaXRfXyhzZWxmLCBwb3NzaXplKQorCQltYWtlZm9udG1lbnUoKQorCQlzZWxmLl9jYWxsYmFjayA9IGNhbGxiYWNrCisJCXNlbGYuX2VuYWJsZWQgPSAxCisJCisJZGVmIG9wZW4oc2VsZik6CisJCXNlbGYuX2NhbGNib3VuZHMoKQorCQorCWRlZiBjbG9zZShzZWxmKToKKwkJcGFzcworCQorCWRlZiBzZXQoc2VsZik6CisJCXJhaXNlIFdiYXNlLldpZGdldHNFcnJvciwgImNhbid0IGNoYW5nZSBmb250IG1lbnUgd2lkZ2V0IgorCQorCWRlZiBfbWVudV9jYWxsYmFjayhzZWxmLCBpZCwgaXRlbSk6CisJCWZvbnRuYW1lID0gc2VsZi5tZW51Lm1lbnUuR2V0TWVudUl0ZW1UZXh0KGl0ZW0pCisJCWlmIHNlbGYuX2NhbGxiYWNrOgorCQkJV2Jhc2UuQ2FsbGJhY2tDYWxsKHNlbGYuX2NhbGxiYWNrLCAwLCBmb250bmFtZSkKKworCWRlZiBjbGljayhzZWxmLCBwb2ludCwgbW9kaWZpZXJzKToKKwkJaWYgbm90IHNlbGYuX2VuYWJsZWQ6CisJCQlyZXR1cm4KKwkJbWFrZWZvbnRtZW51KCkKKwkJcmV0dXJuIFBvcHVwTWVudS5jbGljayhzZWxmLCBwb2ludCwgbW9kaWZpZXJzKQorCQorCitkZWYgbWFrZWZvbnRtZW51KCk6CisJaWYgRm9udE1lbnUubWVudSBpcyBub3QgTm9uZToKKwkJcmV0dXJuCisJaW1wb3J0IFcKKwlGb250TWVudS5tZW51ID0gV0ZyYW1lV29ya1BhdGNoLk1lbnUoVy5nZXRhcHBsaWNhdGlvbigpLm1lbnViYXIsICdGb28nLCAtMSkKKwlXLlNldEN1cnNvcignd2F0Y2gnKQorCWZvciBpIGluIHJhbmdlKEZvbnRNZW51Lm1lbnUubWVudS5Db3VudE1JdGVtcygpLCAwLCAtMSk6CisJCUZvbnRNZW51Lm1lbnUubWVudS5EZWxldGVNZW51SXRlbShpKQorCUZvbnRNZW51Lm1lbnUubWVudS5BcHBlbmRSZXNNZW51KCdGT05EJykKKworCitkZWYgX2dldGZvbnRsaXN0KCk6CisJaW1wb3J0IFJlcworCWZvbnRuYW1lcyA9IFtdCisJZm9yIGkgaW4gcmFuZ2UoMSwgUmVzLkNvdW50UmVzb3VyY2VzKCdGT05EJykgKyAxKToKKwkJciA9IFJlcy5HZXRJbmRSZXNvdXJjZSgnRk9ORCcsIGkpCisJCWZvbnRuYW1lcy5hcHBlbmQoci5HZXRSZXNJbmZvKClbMl0pCisJcmV0dXJuIGZvbnRuYW1lcwpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1dxdWlja3RpbWUucHkgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvV3F1aWNrdGltZS5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5hZGZkYWRiCi0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1dxdWlja3RpbWUucHkKQEAgLTAsMCArMSwxMTkgQEAKK2ltcG9ydCBvcworaW1wb3J0IFFkCitpbXBvcnQgV2luCitpbXBvcnQgUXQsIFF1aWNrVGltZQoraW1wb3J0IFcKK2ltcG9ydCBtYWNmcworaW1wb3J0IEV2dCwgRXZlbnRzCisKK19tb3ZpZXNpbml0aWFsaXplZCA9IDAKKworZGVmIEVudGVyTW92aWVzKCk6CisJZ2xvYmFsIF9tb3ZpZXNpbml0aWFsaXplZAorCWlmIG5vdCBfbW92aWVzaW5pdGlhbGl6ZWQ6CisJCVF0LkVudGVyTW92aWVzKCkKKwkJX21vdmllc2luaXRpYWxpemVkID0gMQorCitjbGFzcyBNb3ZpZShXLldpZGdldCk6CisJCisJZGVmIF9faW5pdF9fKHNlbGYsIHBvc3NpemUpOgorCQlFbnRlck1vdmllcygpCisJCXNlbGYubW92aWUgPSBOb25lCisJCXNlbGYucnVubmluZyA9IDAKKwkJVy5XaWRnZXQuX19pbml0X18oc2VsZiwgcG9zc2l6ZSkKKwkKKwlkZWYgYWRqdXN0KHNlbGYsIG9sZGJvdW5kcyk6CisJCXNlbGYuU2V0UG9ydCgpCisJCVdpbi5JbnZhbFJlY3Qob2xkYm91bmRzKQorCQlXaW4uSW52YWxSZWN0KHNlbGYuX2JvdW5kcykKKwkJc2VsZi5jYWxjbW92aWVib3goKQorCQorCWRlZiBzZXQoc2VsZiwgcGF0aF9vcl9mc3MsIHN0YXJ0ID0gMCk6CisJCXNlbGYuU2V0UG9ydCgpCisJCWlmIHNlbGYubW92aWU6CisJCQkjV2luLkludmFsUmVjdChzZWxmLm1vdmllLkdldE1vdmllQm94KCkpCisJCQlRZC5QYWludFJlY3Qoc2VsZi5tb3ZpZS5HZXRNb3ZpZUJveCgpKQorCQlpZiB0eXBlKHBhdGhfb3JfZnNzKSA9PSB0eXBlKCcnKToKKwkJCXBhdGggPSBwYXRoX29yX2ZzcworCQkJZnNzID0gbWFjZnMuRlNTcGVjKHBhdGgpCisJCWVsc2U6CisJCQlwYXRoID0gcGF0aF9vcl9mc3MuYXNfcGF0aG5hbWUoKQorCQkJZnNzID0gcGF0aF9vcl9mc3MKKwkJc2VsZi5tb3ZpZXRpdGxlID0gb3MucGF0aC5iYXNlbmFtZShwYXRoKQorCQltb3ZpZVJlc1JlZiA9IFF0Lk9wZW5Nb3ZpZUZpbGUoZnNzLCAxKQorCQlzZWxmLm1vdmllLCBkdW1teSA9IFF0Lk5ld01vdmllRnJvbUZpbGUobW92aWVSZXNSZWYsIFF1aWNrVGltZS5uZXdNb3ZpZUFjdGl2ZSkKKwkJc2VsZi5tb3ZpZWJveCA9IHNlbGYubW92aWUuR2V0TW92aWVCb3goKQorCQlzZWxmLmNhbGNtb3ZpZWJveCgpCisJCVFkLk9ic2N1cmVDdXJzb3IoKQkjIFhYWCBkb2VzIHRoaXMgd29yayBhdCBhbGw/CisJCXNlbGYubW92aWUuR29Ub0JlZ2lubmluZ09mTW92aWUoKQorCQlpZiBzdGFydDoKKwkJCXNlbGYubW92aWUuU3RhcnRNb3ZpZSgpCisJCQlzZWxmLnJ1bm5pbmcgPSAxCisJCWVsc2U6CisJCQlzZWxmLnJ1bm5pbmcgPSAwCisJCQlzZWxmLm1vdmllLk1vdmllc1Rhc2soMCkKKwkKKwlkZWYgZ2V0KHNlbGYpOgorCQlyZXR1cm4gc2VsZi5tb3ZpZQorCQorCWRlZiBnZXRtb3ZpZXRpdGxlKHNlbGYpOgorCQlyZXR1cm4gc2VsZi5tb3ZpZXRpdGxlCisJCisJZGVmIHN0YXJ0KHNlbGYpOgorCQlpZiBzZWxmLm1vdmllOgorCQkJUWQuT2JzY3VyZUN1cnNvcigpCisJCQlzZWxmLm1vdmllLlN0YXJ0TW92aWUoKQorCQkJc2VsZi5ydW5uaW5nID0gMQorCQorCWRlZiBzdG9wKHNlbGYpOgorCQlpZiBzZWxmLm1vdmllOgorCQkJc2VsZi5tb3ZpZS5TdG9wTW92aWUoKQorCQkJc2VsZi5ydW5uaW5nID0gMAorCQorCWRlZiByZXdpbmQoc2VsZik6CisJCWlmIHNlbGYubW92aWU6CisJCQlzZWxmLm1vdmllLkdvVG9CZWdpbm5pbmdPZk1vdmllKCkKKwkKKwlkZWYgY2FsY21vdmllYm94KHNlbGYpOgorCQlpZiBub3Qgc2VsZi5tb3ZpZToKKwkJCXJldHVybgorCQltbCwgbXQsIG1yLCBtYiA9IHNlbGYubW92aWVib3gKKwkJd2wsIHd0LCB3ciwgd2IgPSB3aWRnZXRib3ggPSBzZWxmLl9ib3VuZHMKKwkJbWhlaWdodCA9IG1iIC0gbXQKKwkJbXdpZHRoID0gbXIgLSBtbAorCQl3aGVpZ2h0ID0gd2IgLSB3dAorCQl3d2lkdGggPSB3ciAtIHdsCisJCWlmIChtaGVpZ2h0ICogMiA8IHdoZWlnaHQpIGFuZCAobXdpZHRoICogMiA8IHd3aWR0aCk6CisJCQlzY2FsZSA9IDIKKwkJZWxpZiBtaGVpZ2h0ID4gd2hlaWdodCBvciBtd2lkdGggPiB3d2lkdGg6CisJCQlzY2FsZSA9IG1pbihmbG9hdCh3aGVpZ2h0KSAvIG1oZWlnaHQsIGZsb2F0KHd3aWR0aCkgLyBtd2lkdGgpCisJCWVsc2U6CisJCQlzY2FsZSA9IDEKKwkJbXdpZHRoLCBtaGVpZ2h0ID0gbXdpZHRoICogc2NhbGUsIG1oZWlnaHQgKiBzY2FsZQorCQltbCwgbXQgPSB3bCArICh3d2lkdGggLSBtd2lkdGgpIC8gMiwgd3QgKyAod2hlaWdodCAtIG1oZWlnaHQpIC8gMgorCQltciwgbWIgPSBtbCArIG13aWR0aCwgbXQgKyBtaGVpZ2h0CisJCXNlbGYubW92aWUuU2V0TW92aWVCb3goKG1sLCBtdCwgbXIsIG1iKSkKKwkKKwlkZWYgaWRsZShzZWxmLCAqYXJncyk6CisJCWlmIHNlbGYubW92aWU6CisJCQlpZiBub3Qgc2VsZi5tb3ZpZS5Jc01vdmllRG9uZSgpIGFuZCBzZWxmLnJ1bm5pbmc6CisJCQkJUWQuT2JzY3VyZUN1cnNvcigpCisJCQkJd2hpbGUgMToKKwkJCQkJc2VsZi5tb3ZpZS5Nb3ZpZXNUYXNrKDApCisJCQkJCWdvdG9uZSwgZXZlbnQgPSBFdnQuRXZlbnRBdmFpbChFdmVudHMuZXZlcnlFdmVudCkKKwkJCQkJaWYgZ290b25lIG9yIHNlbGYubW92aWUuSXNNb3ZpZURvbmUoKToKKwkJCQkJCWJyZWFrCisJCQllbGlmIHNlbGYucnVubmluZzoKKwkJCQlib3ggPSBzZWxmLm1vdmllLkdldE1vdmllQm94KCkKKwkJCQlzZWxmLlNldFBvcnQoKQorCQkJCVdpbi5JbnZhbFJlY3QoYm94KQorCQkJCXNlbGYubW92aWUgPSBOb25lCisJCQkJc2VsZi5ydW5uaW5nID0gMAorCQorCWRlZiBkcmF3KHNlbGYsIHZpc1JnbiA9IE5vbmUpOgorCQlpZiBzZWxmLl92aXNpYmxlOgorCQkJUWQuUGFpbnRSZWN0KHNlbGYuX2JvdW5kcykKKwkJCWlmIHNlbGYubW92aWU6CisJCQkJc2VsZi5tb3ZpZS5VcGRhdGVNb3ZpZSgpCisJCQkJc2VsZi5tb3ZpZS5Nb3ZpZXNUYXNrKDApCisKZGlmZiAtLWdpdCBhL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XdGV4dC5weSBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XdGV4dC5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi4yNjU0Y2MzCi0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1d0ZXh0LnB5CkBAIC0wLDAgKzEsODgyIEBACitpbXBvcnQgUWQKK2ltcG9ydCBURQoraW1wb3J0IEZtCitpbXBvcnQgd2FzdGUKK2ltcG9ydCBXQVNURWNvbnN0CitpbXBvcnQgUmVzCitpbXBvcnQgRXZ0CitpbXBvcnQgRXZlbnRzCitpbXBvcnQgU2NyYXAKK2ltcG9ydCBzdHJpbmcKKworaW1wb3J0IFdpbgoraW1wb3J0IFdiYXNlCitpbXBvcnQgV2NvbnRyb2xzCitmcm9tIFNwZWNpYWxLZXlzIGltcG9ydCAqCitpbXBvcnQgUHlGb250aWZ5Citmcm9tIHR5cGVzIGltcG9ydCAqCitpbXBvcnQgRm9udHMKK2ltcG9ydCBUZXh0RWRpdAorCisKKworY2xhc3MgVGV4dEJveChXYmFzZS5XaWRnZXQpOgorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBwb3NzaXplLCB0ZXh0ID0gIiIsIGFsaWduID0gVGV4dEVkaXQudGVKdXN0TGVmdCwgCisJCQkJZm9udHNldHRpbmdzID0gKCJNb25hY28iLCAwLCA5LCAoMCwgMCwgMCkpLAorCQkJCWJhY2tjb2xvciA9ICgweGZmZmYsIDB4ZmZmZiwgMHhmZmZmKQorCQkJCSk6CisJCisJCVdiYXNlLldpZGdldC5fX2luaXRfXyhzZWxmLCBwb3NzaXplKQorCQlzZWxmLmZvbnRzZXR0aW5ncyA9IGZvbnRzZXR0aW5ncworCQlzZWxmLnRleHQgPSB0ZXh0CisJCXNlbGYuYWxpZ24gPSBhbGlnbgorCQlzZWxmLmJhY2tjb2xvciA9IGJhY2tjb2xvcgkjIFNldHRpbmdzIG9mIGVkaXRvciBhZGRlZCBieSBQZXRyIDkvNy85NworCQorCWRlZiBkcmF3KHNlbGYsIHZpc1JnbiA9IE5vbmUpOgorCQlpZiBzZWxmLl92aXNpYmxlOgorCQkJKGZvbnQsIHN0eWxlLCBzaXplLCBjb2xvcikgPSBzZWxmLmZvbnRzZXR0aW5ncworCQkJZm9udGlkID0gR2V0Rk51bShmb250KQorCQkJc2F2ZXN0YXRlID0gUWQuR2V0UGVuU3RhdGUoKQorCQkJUWQuVGV4dEZvbnQoZm9udGlkKQorCQkJUWQuVGV4dEZhY2Uoc3R5bGUpCisJCQlRZC5UZXh0U2l6ZShzaXplKQorCQkJUWQuUkdCRm9yZUNvbG9yKGNvbG9yKQorCQkJUWQuUkdCQmFja0NvbG9yKHNlbGYuYmFja2NvbG9yKQkJIyBBZGRlZCBieSBQZXRyIDkvNy85NworCQkJVEUuVEVUZXh0Qm94KHNlbGYudGV4dCwgc2VsZi5fYm91bmRzLCBzZWxmLmFsaWduKQorCQkJUWQuUkdCQmFja0NvbG9yKCgweGZmZmYsIDB4ZmZmZiwgMHhmZmZmKSkJIyBSZXNldCBjb2xvciBBZGRlZCBieSBQZXRyIDkvNy85NworCQkJUWQuU2V0UGVuU3RhdGUoc2F2ZXN0YXRlKQorCQorCWRlZiBnZXQoc2VsZik6CisJCXJldHVybiBzZWxmLnRleHQKKwkKKwlkZWYgc2V0KHNlbGYsIHRleHQpOgorCQlzZWxmLnRleHQgPSB0ZXh0CisJCWlmIHNlbGYuX3BhcmVudHdpbmRvdyBhbmQgc2VsZi5fcGFyZW50d2luZG93LndpZDoKKwkJCXNlbGYuU2V0UG9ydCgpCisJCQlzZWxmLmRyYXcoKQorCisKK2NsYXNzIFNjcm9sbFdpZGdldDoKKwkKKwkjIHRvIGJlIG92ZXJyaWRkZW4KKwlkZWYgZ2V0c2Nyb2xsYmFydmFsdWVzKHNlbGYpOgorCQlyZXR1cm4gTm9uZSwgTm9uZQorCQorCSMgaW50ZXJuYWwgbWV0aG9kCisJZGVmIHVwZGF0ZXNjcm9sbGJhcnMoc2VsZik6CisJCXZ4LCB2eSA9IHNlbGYuZ2V0c2Nyb2xsYmFydmFsdWVzKCkKKwkJaWYgc2VsZi5fcGFyZW50Ll9iYXJ4OgorCQkJaWYgdnggPD4gTm9uZToKKwkJCQlzZWxmLl9wYXJlbnQuX2JhcnguZW5hYmxlKDEpCisJCQkJc2VsZi5fcGFyZW50Ll9iYXJ4LnNldCh2eCkKKwkJCWVsc2U6CisJCQkJc2VsZi5fcGFyZW50Ll9iYXJ4LmVuYWJsZSgwKQorCQlpZiBzZWxmLl9wYXJlbnQuX2Jhcnk6CisJCQlpZiB2eSA8PiBOb25lOgorCQkJCXNlbGYuX3BhcmVudC5fYmFyeS5lbmFibGUoMSkKKwkJCQlzZWxmLl9wYXJlbnQuX2Jhcnkuc2V0KHZ5KQorCQkJZWxzZToKKwkJCQlzZWxmLl9wYXJlbnQuX2JhcnkuZW5hYmxlKDApCisJCisKK1VORE9MQUJFTFMgPSBbCSMgSW5kZXhlZCBieSBXRUdldFVuZG9JbmZvKCkgdmFsdWUKKwlOb25lLCAiIiwgInR5cGluZyIsICJDdXQiLCAiUGFzdGUiLCAiQ2xlYXIiLCAiRHJhZyIsICJTdHlsZSJdCisJCitjbGFzcyBFZGl0VGV4dChXYmFzZS5TZWxlY3RhYmxlV2lkZ2V0LCBTY3JvbGxXaWRnZXQpOgorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBwb3NzaXplLCB0ZXh0ID0gIiIsIAorCQkJCWNhbGxiYWNrID0gTm9uZSwgaW5zZXQgPSAoMywgMyksIAorCQkJCWZvbnRzZXR0aW5ncyA9ICgiUHl0aG9uLVNhbnMiLCAwLCA5LCAoMCwgMCwgMCkpLAorCQkJCXJlYWRvbmx5ID0gMCk6CisJCQkJCisJCVdiYXNlLlNlbGVjdGFibGVXaWRnZXQuX19pbml0X18oc2VsZiwgcG9zc2l6ZSkKKwkJc2VsZi50ZW1wdGV4dCA9IHRleHQKKwkJc2VsZi50ZWQgPSBOb25lCisJCXNlbGYuc2VsZWN0aW9uID0gTm9uZQorCQlzZWxmLl9jYWxsYmFjayA9IGNhbGxiYWNrCisJCXNlbGYuY2hhbmdlZCA9IDAKKwkJc2VsZi5zZWxjaGFuZ2VkID0gMAorCQlzZWxmLl9zZWxlY3RlZCA9IDAKKwkJc2VsZi5fZW5hYmxlZCA9IDEKKwkJc2VsZi53cmFwID0gMQorCQlzZWxmLnJlYWRvbmx5ID0gcmVhZG9ubHkKKwkJc2VsZi5mb250c2V0dGluZ3MgPSBmb250c2V0dGluZ3MKKwkJaWYgdHlwZShpbnNldCkgPD4gVHVwbGVUeXBlOgorCQkJc2VsZi5pbnNldCA9IChpbnNldCwgaW5zZXQpCisJCWVsc2U6CisJCQlzZWxmLmluc2V0ID0gaW5zZXQKKwkKKwlkZWYgb3BlbihzZWxmKToKKwkJaWYgbm90IGhhc2F0dHIoc2VsZi5fcGFyZW50LCAiX2JhcngiKToKKwkJCXNlbGYuX3BhcmVudC5fYmFyeCA9IE5vbmUKKwkJaWYgbm90IGhhc2F0dHIoc2VsZi5fcGFyZW50LCAiX2JhcnkiKToKKwkJCXNlbGYuX3BhcmVudC5fYmFyeSA9IE5vbmUKKwkJc2VsZi5fY2FsY2JvdW5kcygpCisJCXNlbGYuU2V0UG9ydCgpCisJCXZpZXdyZWN0LCBkZXN0cmVjdCA9IHNlbGYuX2NhbGN0ZXh0Ym91bmRzKCkKKwkJZmxhZ3MgPSBzZWxmLl9nZXRmbGFncygpCisJCXNlbGYudGVkID0gd2FzdGUuV0VOZXcoZGVzdHJlY3QsIHZpZXdyZWN0LCBmbGFncykKKwkJc2VsZi50ZWQuV0VJbnN0YWxsVGFiSG9va3MoKQorCQlzZWxmLnRlZC5XRVNldEFsaWdubWVudChXQVNURWNvbnN0LndlRmx1c2hMZWZ0KQorCQlzZWxmLnNldGZvbnRzZXR0aW5ncyhzZWxmLmZvbnRzZXR0aW5ncykKKwkJc2VsZi50ZWQuV0VVc2VUZXh0KFJlcy5SZXNvdXJjZShzZWxmLnRlbXB0ZXh0KSkKKwkJc2VsZi50ZWQuV0VDYWxUZXh0KCkKKwkJaWYgc2VsZi5zZWxlY3Rpb246CisJCQlzZWxmLnNldHNlbGVjdGlvbihzZWxmLnNlbGVjdGlvblswXSwgc2VsZi5zZWxlY3Rpb25bMV0pCisJCQlzZWxmLnNlbGVjdGlvbiA9IE5vbmUKKwkJZWxzZToKKwkJCXNlbGYuc2VsdmlldygpCisJCXNlbGYudGVtcHRleHQgPSBOb25lCisJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCXNlbGYuYmluZCgicGFnZXVwIiwgc2VsZi5zY3JvbGxwYWdldXApCisJCXNlbGYuYmluZCgicGFnZWRvd24iLCBzZWxmLnNjcm9sbHBhZ2Vkb3duKQorCQlzZWxmLmJpbmQoInRvcCIsIHNlbGYuc2Nyb2xsdG9wKQorCQlzZWxmLmJpbmQoImJvdHRvbSIsIHNlbGYuc2Nyb2xsYm90dG9tKQorCQlzZWxmLnNlbGNoYW5nZWQgPSAwCisJCisJZGVmIGNsb3NlKHNlbGYpOgorCQlzZWxmLl9wYXJlbnQuX2JhcnggPSBOb25lCisJCXNlbGYuX3BhcmVudC5fYmFyeSA9IE5vbmUKKwkJc2VsZi50ZWQgPSBOb25lCisJCXNlbGYudGVtcHRleHQgPSBOb25lCisJCVdiYXNlLlNlbGVjdGFibGVXaWRnZXQuY2xvc2Uoc2VsZikKKwkKKwlkZWYgZ2V0Zm9udHNldHRpbmdzKHNlbGYpOgorCQlpbXBvcnQgUmVzCisJCShmb250LCBzdHlsZSwgc2l6ZSwgY29sb3IpID0gc2VsZi50ZWQuV0VHZXRSdW5JbmZvKDApWzRdCisJCWZvbnQgPSBHZXRGTmFtZShmb250KQorCQlyZXR1cm4gKGZvbnQsIHN0eWxlLCBzaXplLCBjb2xvcikKKwkKKwlkZWYgc2V0Zm9udHNldHRpbmdzKHNlbGYsIChmb250LCBzdHlsZSwgc2l6ZSwgY29sb3IpKToKKwkJc2VsZi5TZXRQb3J0KCkKKwkJaWYgdHlwZShmb250KSA8PiBTdHJpbmdUeXBlOgorCQkJZm9udCA9IEdldEZOYW1lKGZvbnQpCisJCXNlbGYuZm9udHNldHRpbmdzID0gKGZvbnQsIHN0eWxlLCBzaXplLCBjb2xvcikKKwkJZm9udGlkID0gR2V0Rk51bShmb250KQorCQlyZWFkb25seSA9IHNlbGYudGVkLldFRmVhdHVyZUZsYWcoV0FTVEVjb25zdC53ZUZSZWFkT25seSwgLTEpCisJCWlmIHJlYWRvbmx5OgorCQkJc2VsZi50ZWQuV0VGZWF0dXJlRmxhZyhXQVNURWNvbnN0LndlRlJlYWRPbmx5LCAwKQorCQlzZWxmLnRlZC5XRUZlYXR1cmVGbGFnKFdBU1RFY29uc3Qud2VGSW5oaWJpdFJlY2FsLCAxKQorCQlzZWxzdGFydCwgc2VsZW5kID0gc2VsZi50ZWQuV0VHZXRTZWxlY3Rpb24oKQorCQlzZWxmLnRlZC5XRVNldFNlbGVjdGlvbigwLCBzZWxmLnRlZC5XRUdldFRleHRMZW5ndGgoKSkKKwkJc2VsZi50ZWQuV0VTZXRTdHlsZShXQVNURWNvbnN0LndlRG9GYWNlLCAoMCwgMCwgMCwgKDAsIDAsIDApKSkKKwkJc2VsZi50ZWQuV0VTZXRTdHlsZShXQVNURWNvbnN0LndlRG9GYWNlIHwgCisJCQkJCVdBU1RFY29uc3Qud2VEb0NvbG9yIHwgCisJCQkJCVdBU1RFY29uc3Qud2VEb0ZvbnQgfCAKKwkJCQkJV0FTVEVjb25zdC53ZURvU2l6ZSwgCisJCQkJCShmb250aWQsIHN0eWxlLCBzaXplLCBjb2xvcikpCisJCXNlbGYudGVkLldFRmVhdHVyZUZsYWcoV0FTVEVjb25zdC53ZUZJbmhpYml0UmVjYWwsIDApCisJCXNlbGYudGVkLldFQ2FsVGV4dCgpCisJCXNlbGYudGVkLldFU2V0U2VsZWN0aW9uKHNlbHN0YXJ0LCBzZWxlbmQpCisJCWlmIHJlYWRvbmx5OgorCQkJc2VsZi50ZWQuV0VGZWF0dXJlRmxhZyhXQVNURWNvbnN0LndlRlJlYWRPbmx5LCAxKQorCQl2aWV3cmVjdCA9IHNlbGYudGVkLldFR2V0Vmlld1JlY3QoKQorCQlRZC5FcmFzZVJlY3Qodmlld3JlY3QpCisJCXNlbGYudGVkLldFVXBkYXRlKHNlbGYuX3BhcmVudHdpbmRvdy53aWQuR2V0V2luZG93UG9ydCgpLnZpc1JnbikKKwkJc2VsZi5zZWxjaGFuZ2VkID0gMQorCQlzZWxmLnVwZGF0ZXNjcm9sbGJhcnMoKQorCQorCWRlZiBhZGp1c3Qoc2VsZiwgb2xkYm91bmRzKToKKwkJc2VsZi5TZXRQb3J0KCkKKwkJaWYgc2VsZi5fc2VsZWN0ZWQgYW5kIHNlbGYuX3BhcmVudHdpbmRvdy5faGFzc2VsZnJhbWVzOgorCQkJV2luLkludmFsUmVjdChRZC5JbnNldFJlY3Qob2xkYm91bmRzLCAtMywgLTMpKQorCQkJV2luLkludmFsUmVjdChRZC5JbnNldFJlY3Qoc2VsZi5fYm91bmRzLCAtMywgLTMpKQorCQllbHNlOgorCQkJV2luLkludmFsUmVjdChvbGRib3VuZHMpCisJCQlXaW4uSW52YWxSZWN0KHNlbGYuX2JvdW5kcykKKwkJdmlld3JlY3QsIGRlc3RyZWN0ID0gc2VsZi5fY2FsY3RleHRib3VuZHMoKQorCQlzZWxmLnRlZC5XRVNldFZpZXdSZWN0KHZpZXdyZWN0KQorCQlzZWxmLnRlZC5XRVNldERlc3RSZWN0KGRlc3RyZWN0KQorCQlpZiBzZWxmLndyYXA6CisJCQlzZWxmLnRlZC5XRUNhbFRleHQoKQorCQlpZiBzZWxmLnRlZC5XRUdldERlc3RSZWN0KClbM10gPCB2aWV3cmVjdFsxXToKKwkJCXNlbGYuc2VsdmlldygpCisJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCisJIyBpbnRlcmZhY2UgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0KKwkjIHNlbGVjdGlvbiBzdHVmZgorCWRlZiBzZWx2aWV3KHNlbGYpOgorCQlzZWxmLnRlZC5XRVNlbFZpZXcoKQorCQorCWRlZiBzZWxlY3RhbGwoc2VsZik6CisJCXNlbGYudGVkLldFU2V0U2VsZWN0aW9uKDAsIHNlbGYudGVkLldFR2V0VGV4dExlbmd0aCgpKQorCQlzZWxmLnNlbGNoYW5nZWQgPSAxCisJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCisJZGVmIHNlbGVjdGxpbmUoc2VsZiwgbGluZW5vLCBjaGFyb2Zmc2V0ID0gMCk6CisJCW5ld3NlbHN0YXJ0LCBuZXdzZWxlbmQgPSBzZWxmLnRlZC5XRUdldExpbmVSYW5nZShsaW5lbm8pCisJCXNlbGYudGVkLldFU2V0U2VsZWN0aW9uKG5ld3NlbHN0YXJ0ICsgY2hhcm9mZnNldCwgbmV3c2VsZW5kKQorCQlzZWxmLnNlbGNoYW5nZWQgPSAxCisJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCisJZGVmIGdldHNlbGVjdGlvbihzZWxmKToKKwkJaWYgc2VsZi50ZWQ6CisJCQlyZXR1cm4gc2VsZi50ZWQuV0VHZXRTZWxlY3Rpb24oKQorCQllbHNlOgorCQkJcmV0dXJuIHNlbGYuc2VsZWN0aW9uCisJCisJZGVmIHNldHNlbGVjdGlvbihzZWxmLCBzZWxzdGFydCwgc2VsZW5kKToKKwkJc2VsZi5zZWxjaGFuZ2VkID0gMQorCQlpZiBzZWxmLnRlZDoKKwkJCXNlbGYudGVkLldFU2V0U2VsZWN0aW9uKHNlbHN0YXJ0LCBzZWxlbmQpCisJCQlzZWxmLnRlZC5XRVNlbFZpZXcoKQorCQkJc2VsZi51cGRhdGVzY3JvbGxiYXJzKCkKKwkJZWxzZToKKwkJCXNlbGYuc2VsZWN0aW9uID0gc2Vsc3RhcnQsIHNlbGVuZAorCQorCWRlZiBvZmZzZXR0b2xpbmUoc2VsZiwgb2Zmc2V0KToKKwkJcmV0dXJuIHNlbGYudGVkLldFT2Zmc2V0VG9MaW5lKG9mZnNldCkKKwkKKwlkZWYgY291bnRsaW5lcyhzZWxmKToKKwkJcmV0dXJuIHNlbGYudGVkLldFQ291bnRMaW5lcygpCisJCisJZGVmIGdldHNlbGVjdGVkdGV4dChzZWxmKToKKwkJc2Vsc3RhcnQsIHNlbGVuZCA9IHNlbGYudGVkLldFR2V0U2VsZWN0aW9uKCkKKwkJcmV0dXJuIHNlbGYudGVkLldFR2V0VGV4dCgpLmRhdGFbc2Vsc3RhcnQ6c2VsZW5kXQorCQorCWRlZiBleHBhbmRzZWxlY3Rpb24oc2VsZik6CisJCW9sZHNlbHN0YXJ0LCBvbGRzZWxlbmQgPSBzZWxmLnRlZC5XRUdldFNlbGVjdGlvbigpCisJCXNlbHN0YXJ0LCBzZWxlbmQgPSBtaW4ob2xkc2Vsc3RhcnQsIG9sZHNlbGVuZCksIG1heChvbGRzZWxzdGFydCwgb2xkc2VsZW5kKQorCQlpZiBzZWxzdGFydCA8PiBzZWxlbmQgYW5kIGNocihzZWxmLnRlZC5XRUdldENoYXIoc2VsZW5kLTEpKSA9PSAnXHInOgorCQkJc2VsZW5kID0gc2VsZW5kIC0gMQorCQluZXdzZWxzdGFydCwgZHVtbXkgPSBzZWxmLnRlZC5XRUZpbmRMaW5lKHNlbHN0YXJ0LCAwKQorCQlkdW1teSwgbmV3c2VsZW5kID0gc2VsZi50ZWQuV0VGaW5kTGluZShzZWxlbmQsIDApCisJCWlmIG9sZHNlbHN0YXJ0IDw+IG5ld3NlbHN0YXJ0IG9yICBvbGRzZWxlbmQgPD4gbmV3c2VsZW5kOgorCQkJc2VsZi50ZWQuV0VTZXRTZWxlY3Rpb24obmV3c2Vsc3RhcnQsIG5ld3NlbGVuZCkKKwkJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCXNlbGYuc2VsY2hhbmdlZCA9IDEKKwkKKwlkZWYgaW5zZXJ0KHNlbGYsIHRleHQpOgorCQlzZWxmLnRlZC5XRUluc2VydCh0ZXh0LCBOb25lLCBOb25lKQorCQlzZWxmLmNoYW5nZWQgPSAxCisJCXNlbGYuc2VsY2hhbmdlZCA9IDEKKwkKKwlkZWYgc2hpZnRsZWZ0KHNlbGYpOgorCQlzZWxmLmV4cGFuZHNlbGVjdGlvbigpCisJCXNlbHN0YXJ0LCBzZWxlbmQgPSBzZWxmLnRlZC5XRUdldFNlbGVjdGlvbigpCisJCXNlbHN0YXJ0LCBzZWxlbmQgPSBtaW4oc2Vsc3RhcnQsIHNlbGVuZCksIG1heChzZWxzdGFydCwgc2VsZW5kKQorCQlzbmlwcGV0ID0gc2VsZi5nZXRzZWxlY3RlZHRleHQoKQorCQlsaW5lcyA9IHN0cmluZy5zcGxpdChzbmlwcGV0LCAnXHInKQorCQlmb3IgaSBpbiByYW5nZShsZW4obGluZXMpKToKKwkJCWlmIGxpbmVzW2ldWzoxXSA9PSAnXHQnOgorCQkJCWxpbmVzW2ldID0gbGluZXNbaV1bMTpdCisJCXNuaXBwZXQgPSBzdHJpbmcuam9pbihsaW5lcywgJ1xyJykKKwkJc2VsZi5pbnNlcnQoc25pcHBldCkKKwkJc2VsZi50ZWQuV0VTZXRTZWxlY3Rpb24oc2Vsc3RhcnQsIHNlbHN0YXJ0ICsgbGVuKHNuaXBwZXQpKQorCQorCWRlZiBzaGlmdHJpZ2h0KHNlbGYpOgorCQlzZWxmLmV4cGFuZHNlbGVjdGlvbigpCisJCXNlbHN0YXJ0LCBzZWxlbmQgPSBzZWxmLnRlZC5XRUdldFNlbGVjdGlvbigpCisJCXNlbHN0YXJ0LCBzZWxlbmQgPSBtaW4oc2Vsc3RhcnQsIHNlbGVuZCksIG1heChzZWxzdGFydCwgc2VsZW5kKQorCQlzbmlwcGV0ID0gc2VsZi5nZXRzZWxlY3RlZHRleHQoKQorCQlsaW5lcyA9IHN0cmluZy5zcGxpdChzbmlwcGV0LCAnXHInKQorCQlmb3IgaSBpbiByYW5nZShsZW4obGluZXMpIC0gMSk6CisJCQlsaW5lc1tpXSA9ICdcdCcgKyBsaW5lc1tpXQorCQlzbmlwcGV0ID0gc3RyaW5nLmpvaW4obGluZXMsICdccicpCisJCXNlbGYuaW5zZXJ0KHNuaXBwZXQpCisJCXNlbGYudGVkLldFU2V0U2VsZWN0aW9uKHNlbHN0YXJ0LCBzZWxzdGFydCArIGxlbihzbmlwcGV0KSkKKwkKKwkjIHRleHQKKwlkZWYgc2V0KHNlbGYsIHRleHQpOgorCQlpZiBub3Qgc2VsZi50ZWQ6CisJCQlzZWxmLnRlbXB0ZXh0ID0gdGV4dAorCQllbHNlOgorCQkJc2VsZi50ZWQuV0VVc2VUZXh0KFJlcy5SZXNvdXJjZSh0ZXh0KSkKKwkJCXNlbGYudGVkLldFQ2FsVGV4dCgpCisJCQlzZWxmLlNldFBvcnQoKQorCQkJdmlld3JlY3QsIGRlc3RyZWN0ID0gc2VsZi5fY2FsY3RleHRib3VuZHMoKQorCQkJc2VsZi50ZWQuV0VTZXRWaWV3UmVjdCh2aWV3cmVjdCkKKwkJCXNlbGYudGVkLldFU2V0RGVzdFJlY3QoZGVzdHJlY3QpCisJCQlyZ24gPSBRZC5OZXdSZ24oKQorCQkJUWQuUmVjdFJnbihyZ24sIHZpZXdyZWN0KQorCQkJUWQuRXJhc2VSZWN0KHZpZXdyZWN0KQorCQkJc2VsZi5kcmF3KHJnbikKKwkJCSNXaW4uSW52YWxSZWN0KHNlbGYudGVkLldFR2V0Vmlld1JlY3QoKSkKKwkJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCisJZGVmIGdldChzZWxmKToKKwkJaWYgbm90IHNlbGYuX3BhcmVudDoKKwkJCXJldHVybiBzZWxmLnRlbXB0ZXh0CisJCWVsc2U6CisJCQlyZXR1cm4gc2VsZi50ZWQuV0VHZXRUZXh0KCkuZGF0YQorCQorCSMgZXZlbnRzCisJZGVmIGtleShzZWxmLCBjaGFyLCBldmVudCk6CisJCSh3aGF0LCBtZXNzYWdlLCB3aGVuLCB3aGVyZSwgbW9kaWZpZXJzKSA9IGV2ZW50CisJCWlmIHNlbGYuX2VuYWJsZWQgYW5kIG5vdCBtb2RpZmllcnMgJiBFdmVudHMuY21kS2V5IG9yIGNoYXIgaW4gYXJyb3drZXlzOgorCQkJc2VsZi50ZWQuV0VLZXkob3JkKGNoYXIpLCBtb2RpZmllcnMpCisJCQlpZiBjaGFyIG5vdCBpbiBuYXZpZ2F0aW9ua2V5czoKKwkJCQlzZWxmLmNoYW5nZWQgPSAxCisJCQlpZiBjaGFyIG5vdCBpbiBzY3JvbGxrZXlzOgorCQkJCXNlbGYuc2VsY2hhbmdlZCA9IDEKKwkJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCQlpZiBzZWxmLl9jYWxsYmFjazoKKwkJCQlXYmFzZS5DYWxsYmFja0NhbGwoc2VsZi5fY2FsbGJhY2ssIDAsIGNoYXIsIG1vZGlmaWVycykKKwkKKwlkZWYgY2xpY2soc2VsZiwgcG9pbnQsIG1vZGlmaWVycyk6CisJCWlmIG5vdCBzZWxmLl9lbmFibGVkOgorCQkJcmV0dXJuCisJCXNlbGYudGVkLldFQ2xpY2socG9pbnQsIG1vZGlmaWVycywgRXZ0LlRpY2tDb3VudCgpKQorCQlzZWxmLnNlbGNoYW5nZWQgPSAxCisJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCXJldHVybiAxCisJCisJZGVmIGlkbGUoc2VsZik6CisJCXNlbGYuU2V0UG9ydCgpCisJCXNlbGYudGVkLldFSWRsZSgpCisJCisJZGVmIHJvbGxvdmVyKHNlbGYsIHBvaW50LCBvbm9mZik6CisJCWlmIG9ub2ZmOgorCQkJV2Jhc2UuU2V0Q3Vyc29yKCJpQmVhbSIpCisJCisJZGVmIGFjdGl2YXRlKHNlbGYsIG9ub2ZmKToKKwkJc2VsZi5fYWN0aXZhdGVkID0gb25vZmYKKwkJaWYgc2VsZi5fc2VsZWN0ZWQgYW5kIHNlbGYuX3Zpc2libGU6CisJCQlpZiBvbm9mZjoKKwkJCQlzZWxmLnRlZC5XRUFjdGl2YXRlKCkKKwkJCWVsc2U6CisJCQkJc2VsZi50ZWQuV0VEZWFjdGl2YXRlKCkKKwkJCWlmIHNlbGYuX3NlbGVjdGVkOgorCQkJCXNlbGYuZHJhd3NlbGZyYW1lKG9ub2ZmKQorCQorCWRlZiBzZWxlY3Qoc2VsZiwgb25vZmYsIGlzY2xpY2sgPSAwKToKKwkJaWYgV2Jhc2UuU2VsZWN0YWJsZVdpZGdldC5zZWxlY3Qoc2VsZiwgb25vZmYpOgorCQkJcmV0dXJuCisJCXNlbGYuU2V0UG9ydCgpCisJCWlmIG9ub2ZmOgorCQkJc2VsZi50ZWQuV0VBY3RpdmF0ZSgpCisJCQlpZiBzZWxmLl9wYXJlbnR3aW5kb3cuX3RhYmJhYmxlIGFuZCBub3QgaXNjbGljazoKKwkJCQlzZWxmLnNlbGVjdGFsbCgpCisJCWVsc2U6CisJCQlzZWxmLnRlZC5XRURlYWN0aXZhdGUoKQorCQlzZWxmLmRyYXdzZWxmcmFtZShvbm9mZikKKwkKKwlkZWYgZHJhdyhzZWxmLCB2aXNSZ24gPSBOb25lKToKKwkJaWYgc2VsZi5fdmlzaWJsZToKKwkJCWlmIG5vdCB2aXNSZ246CisJCQkJdmlzUmduID0gc2VsZi5fcGFyZW50d2luZG93LndpZC5HZXRXaW5kb3dQb3J0KCkudmlzUmduCisJCQlzZWxmLnRlZC5XRVVwZGF0ZSh2aXNSZ24pCisJCQlpZiBzZWxmLl9zZWxlY3RlZCBhbmQgc2VsZi5fYWN0aXZhdGVkOgorCQkJCXNlbGYuZHJhd3NlbGZyYW1lKDEpCisJCQlRZC5GcmFtZVJlY3Qoc2VsZi5fYm91bmRzKQorCQorCSMgc2Nyb2xsaW5nCisJZGVmIHNjcm9sbHBhZ2V1cChzZWxmKToKKwkJaWYgc2VsZi5fcGFyZW50Ll9iYXJ5IGFuZCBzZWxmLl9wYXJlbnQuX2JhcnkuX2VuYWJsZWQ6CisJCQlzZWxmLnZzY3JvbGwoIisrIikKKwkKKwlkZWYgc2Nyb2xscGFnZWRvd24oc2VsZik6CisJCWlmIHNlbGYuX3BhcmVudC5fYmFyeSBhbmQgc2VsZi5fcGFyZW50Ll9iYXJ5Ll9lbmFibGVkOgorCQkJc2VsZi52c2Nyb2xsKCItLSIpCisJCisJZGVmIHNjcm9sbHRvcChzZWxmKToKKwkJaWYgc2VsZi5fcGFyZW50Ll9iYXJ5IGFuZCBzZWxmLl9wYXJlbnQuX2JhcnkuX2VuYWJsZWQ6CisJCQlzZWxmLnZzY3JvbGwoMCkKKwkJaWYgc2VsZi5fcGFyZW50Ll9iYXJ4IGFuZCBzZWxmLl9wYXJlbnQuX2JhcnguX2VuYWJsZWQ6CisJCQlzZWxmLmhzY3JvbGwoMCkKKwkKKwlkZWYgc2Nyb2xsYm90dG9tKHNlbGYpOgorCQlpZiBzZWxmLl9wYXJlbnQuX2JhcnkgYW5kIHNlbGYuX3BhcmVudC5fYmFyeS5fZW5hYmxlZDoKKwkJCXNlbGYudnNjcm9sbCgzMjc2NykKKwkKKwkjIG1lbnUgaGFuZGxlcnMKKwlkZWYgZG9tZW51X2NvcHkoc2VsZiwgKmFyZ3MpOgorCQlzZWxiZWdpbiwgc2VsZW5kID0gc2VsZi50ZWQuV0VHZXRTZWxlY3Rpb24oKQorCQlpZiBzZWxiZWdpbiA9PSBzZWxlbmQ6CisJCQlyZXR1cm4KKwkJU2NyYXAuWmVyb1NjcmFwKCkKKwkJc2VsZi50ZWQuV0VDb3B5KCkKKwkJc2VsZi51cGRhdGVzY3JvbGxiYXJzKCkKKwkKKwlkZWYgZG9tZW51X2N1dChzZWxmLCAqYXJncyk6CisJCXNlbGJlZ2luLCBzZWxlbmQgPSBzZWxmLnRlZC5XRUdldFNlbGVjdGlvbigpCisJCWlmIHNlbGJlZ2luID09IHNlbGVuZDoKKwkJCXJldHVybgorCQlTY3JhcC5aZXJvU2NyYXAoKQorCQlzZWxmLnRlZC5XRUN1dCgpCisJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCXNlbGYuc2VsdmlldygpCisJCXNlbGYuY2hhbmdlZCA9IDEKKwkJc2VsZi5zZWxjaGFuZ2VkID0gMQorCQlpZiBzZWxmLl9jYWxsYmFjazoKKwkJCVdiYXNlLkNhbGxiYWNrQ2FsbChzZWxmLl9jYWxsYmFjaywgMCwgIiIsIE5vbmUpCisJCisJZGVmIGRvbWVudV9wYXN0ZShzZWxmLCAqYXJncyk6CisJCWlmIG5vdCBzZWxmLnRlZC5XRUNhblBhc3RlKCk6CisJCQlyZXR1cm4KKwkJc2VsZi5zZWx2aWV3KCkKKwkJc2VsZi50ZWQuV0VQYXN0ZSgpCisJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCXNlbGYuY2hhbmdlZCA9IDEKKwkJc2VsZi5zZWxjaGFuZ2VkID0gMQorCQlpZiBzZWxmLl9jYWxsYmFjazoKKwkJCVdiYXNlLkNhbGxiYWNrQ2FsbChzZWxmLl9jYWxsYmFjaywgMCwgIiIsIE5vbmUpCisJCisJZGVmIGRvbWVudV9jbGVhcihzZWxmLCAqYXJncyk6CisJCXNlbGYudGVkLldFRGVsZXRlKCkKKwkJc2VsZi5zZWx2aWV3KCkKKwkJc2VsZi51cGRhdGVzY3JvbGxiYXJzKCkKKwkJc2VsZi5jaGFuZ2VkID0gMQorCQlzZWxmLnNlbGNoYW5nZWQgPSAxCisJCWlmIHNlbGYuX2NhbGxiYWNrOgorCQkJV2Jhc2UuQ2FsbGJhY2tDYWxsKHNlbGYuX2NhbGxiYWNrLCAwLCAiIiwgTm9uZSkKKwkKKwlkZWYgZG9tZW51X3VuZG8oc2VsZiwgKmFyZ3MpOgorCQl3aGljaCwgcmVkbyA9IHNlbGYudGVkLldFR2V0VW5kb0luZm8oKQorCQlpZiBub3Qgd2hpY2g6IAorCQkJcmV0dXJuCisJCXNlbGYudGVkLldFVW5kbygpCisJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCXNlbGYuY2hhbmdlZCA9IDEKKwkJc2VsZi5zZWxjaGFuZ2VkID0gMQorCQlpZiBzZWxmLl9jYWxsYmFjazoKKwkJCVdiYXNlLkNhbGxiYWNrQ2FsbChzZWxmLl9jYWxsYmFjaywgMCwgIiIsIE5vbmUpCisJCisJZGVmIGNhbl91bmRvKHNlbGYsIG1lbnVpdGVtKToKKwkJd2hpY2gsIHJlZG8gPSBzZWxmLnRlZC5XRUdldFVuZG9JbmZvKCkKKwkJd2hpY2ggPSBVTkRPTEFCRUxTW3doaWNoXQorCQlpZiB3aGljaCA9PSBOb25lOiAKKwkJCXJldHVybiBOb25lCisJCWlmIHJlZG86CisJCQl3aGljaCA9ICJSZWRvICIrd2hpY2gKKwkJZWxzZToKKwkJCXdoaWNoID0gIlVuZG8gIit3aGljaAorCQltZW51aXRlbS5zZXR0ZXh0KHdoaWNoKQorCQlyZXR1cm4gMQorCQorCWRlZiBkb21lbnVfc2VsZWN0YWxsKHNlbGYsICphcmdzKToKKwkJc2VsZi5zZWxlY3RhbGwoKQorCQorCSMgcHJpdmF0ZQorCWRlZiBnZXRzY3JvbGxiYXJ2YWx1ZXMoc2VsZik6CisJCWRyID0gc2VsZi50ZWQuV0VHZXREZXN0UmVjdCgpCisJCXZyID0gc2VsZi50ZWQuV0VHZXRWaWV3UmVjdCgpCisJCXZ4ID0gV2NvbnRyb2xzLl9zY2FsZWJhcnZhbHVlKGRyWzBdLCBkclsyXSwgdnJbMF0sIHZyWzJdKQorCQl2eSA9IFdjb250cm9scy5fc2NhbGViYXJ2YWx1ZShkclsxXSwgZHJbM10sIHZyWzFdLCB2clszXSkKKwkJcmV0dXJuIHZ4LCB2eQorCQorCWRlZiB2c2Nyb2xsKHNlbGYsIHZhbHVlKToKKwkJbGluZWhlaWdodCA9IHNlbGYudGVkLldFR2V0SGVpZ2h0KDAsIDEpCisJCWRyID0gc2VsZi50ZWQuV0VHZXREZXN0UmVjdCgpCisJCXZyID0gc2VsZi50ZWQuV0VHZXRWaWV3UmVjdCgpCisJCWRlc3RoZWlnaHQgPSBkclszXSAtIGRyWzFdCisJCXZpZXdoZWlnaHQgPSB2clszXSAtIHZyWzFdCisJCXZpZXdvZmZzZXQgPSBtYXhkZWx0YSA9IHZyWzFdIC0gZHJbMV0KKwkJbWluZGVsdGEgPSB2clszXSAtIGRyWzNdCisJCWlmIHZhbHVlID09ICIrIjoKKwkJCWRlbHRhID0gbGluZWhlaWdodAorCQllbGlmIHZhbHVlID09ICItIjoKKwkJCWRlbHRhID0gLSBsaW5laGVpZ2h0CisJCWVsaWYgdmFsdWUgPT0gIisrIjoKKwkJCWRlbHRhID0gdmlld2hlaWdodCAtIGxpbmVoZWlnaHQKKwkJZWxpZiB2YWx1ZSA9PSAiLS0iOgorCQkJZGVsdGEgPSBsaW5laGVpZ2h0IC0gdmlld2hlaWdodAorCQllbHNlOgkjIGluIHRodW1iCisJCQljdXIgPSAoMzI3NjcgKiB2aWV3b2Zmc2V0KSAvIChkZXN0aGVpZ2h0IC0gdmlld2hlaWdodCkKKwkJCWRlbHRhID0gKGN1ci12YWx1ZSkqKGRlc3RoZWlnaHQgLSB2aWV3aGVpZ2h0KS8zMjc2NworCQkJaWYgYWJzKGRlbHRhIC0gdmlld29mZnNldCkgPD0yOgorCQkJCSMgY29tcGVuc2F0ZSBmb3IgaXJyaXRhdGluZyByb3VuZGluZyBlcnJvcgorCQkJCWRlbHRhID0gdmlld29mZnNldAorCQlkZWx0YSA9IG1pbihtYXhkZWx0YSwgZGVsdGEpCisJCWRlbHRhID0gbWF4KG1pbmRlbHRhLCBkZWx0YSkKKwkJc2VsZi50ZWQuV0VTY3JvbGwoMCwgZGVsdGEpCisJCXNlbGYudXBkYXRlc2Nyb2xsYmFycygpCisJCisJZGVmIGhzY3JvbGwoc2VsZiwgdmFsdWUpOgorCQlkciA9IHNlbGYudGVkLldFR2V0RGVzdFJlY3QoKQorCQl2ciA9IHNlbGYudGVkLldFR2V0Vmlld1JlY3QoKQorCQlkZXN0d2lkdGggPSBkclsyXSAtIGRyWzBdCisJCXZpZXd3aWR0aCA9IHZyWzJdIC0gdnJbMF0KKwkJdmlld29mZnNldCA9IG1heGRlbHRhID0gdnJbMF0gLSBkclswXQorCQltaW5kZWx0YSA9IHZyWzJdIC0gZHJbMl0KKwkJaWYgdmFsdWUgPT0gIisiOgorCQkJZGVsdGEgPSAzMgorCQllbGlmIHZhbHVlID09ICItIjoKKwkJCWRlbHRhID0gLSAzMgorCQllbGlmIHZhbHVlID09ICIrKyI6CisJCQlkZWx0YSA9IDAuNSAqICh2clsyXSAtIHZyWzBdKQorCQllbGlmIHZhbHVlID09ICItLSI6CisJCQlkZWx0YSA9IDAuNSAqICh2clswXSAtIHZyWzJdKQorCQllbHNlOgkjIGluIHRodW1iCisJCQljdXIgPSAoMzI3NjcgKiB2aWV3b2Zmc2V0KSAvIChkZXN0d2lkdGggLSB2aWV3d2lkdGgpCisJCQlkZWx0YSA9IChjdXItdmFsdWUpKihkZXN0d2lkdGggLSB2aWV3d2lkdGgpLzMyNzY3CisJCQlpZiBhYnMoZGVsdGEgLSB2aWV3b2Zmc2V0KSA8PTI6CisJCQkJIyBjb21wZW5zYXRlIGZvciBpcnJpdGF0aW5nIHJvdW5kaW5nIGVycm9yCisJCQkJZGVsdGEgPSB2aWV3b2Zmc2V0CisJCWRlbHRhID0gbWluKG1heGRlbHRhLCBkZWx0YSkKKwkJZGVsdGEgPSBtYXgobWluZGVsdGEsIGRlbHRhKQorCQlzZWxmLnRlZC5XRVNjcm9sbChkZWx0YSwgMCkKKwkJc2VsZi51cGRhdGVzY3JvbGxiYXJzKCkKKwkKKwkjIHNvbWUgaW50ZXJuYWxzCisJZGVmIF9nZXRmbGFncyhzZWxmKToKKwkJZmxhZ3MgPSBXQVNURWNvbnN0LndlRG9BdXRvU2Nyb2xsIHwgV0FTVEVjb25zdC53ZURvTW9ub1N0eWxlZCB8IFwKKwkJCQlXQVNURWNvbnN0LndlRG9VbmRvCisJCWlmIHNlbGYucmVhZG9ubHk6CisJCQlmbGFncyA9IGZsYWdzIHwgV0FTVEVjb25zdC53ZURvUmVhZE9ubHkKKwkJcmV0dXJuIGZsYWdzCisJCisJZGVmIF9nZXR2aWV3cmVjdChzZWxmKToKKwkJcmV0dXJuIFFkLkluc2V0UmVjdChzZWxmLl9ib3VuZHMsIHNlbGYuaW5zZXRbMF0sIHNlbGYuaW5zZXRbMV0pCisJCisJZGVmIF9jYWxjdGV4dGJvdW5kcyhzZWxmKToKKwkJdmlld3JlY3QgPSBsLCB0LCByLCBiID0gc2VsZi5fZ2V0dmlld3JlY3QoKQorCQlpZiBzZWxmLnRlZDoKKwkJCWRsLCBkdCwgZHIsIGRiID0gc2VsZi50ZWQuV0VHZXREZXN0UmVjdCgpCisJCQl2bCwgdnQsIHZyLCB2YiA9IHNlbGYudGVkLldFR2V0Vmlld1JlY3QoKQorCQkJeXNoaWZ0ID0gdCAtIHZ0CisJCQlpZiAoZGIgLSBkdCkgPCAoYiAtIHQpOgorCQkJCWRlc3RyZWN0ID0gdmlld3JlY3QKKwkJCWVsc2U6CisJCQkJZGVzdHJlY3QgPSBsLCBkdCArIHlzaGlmdCwgciwgZGIgKyB5c2hpZnQKKwkJZWxzZToKKwkJCWRlc3RyZWN0ID0gdmlld3JlY3QKKwkJcmV0dXJuIHZpZXdyZWN0LCBkZXN0cmVjdAorCQkKKworY2xhc3MgVGV4dEVkaXRvcihFZGl0VGV4dCk6CisJCisJZGVmIF9faW5pdF9fKHNlbGYsIHBvc3NpemUsIHRleHQgPSAiIiwgY2FsbGJhY2sgPSBOb25lLCB3cmFwID0gMSwgaW5zZXQgPSAoNCwgNCksCisJCQkJZm9udHNldHRpbmdzID0gKCJQeXRob24tU2FucyIsIDAsIDksICgwLCAwLCAwKSksCisJCQkJcmVhZG9ubHkgPSAwKToKKwkJRWRpdFRleHQuX19pbml0X18oc2VsZiwgcG9zc2l6ZSwgdGV4dCwgY2FsbGJhY2ssIGluc2V0LCBmb250c2V0dGluZ3MsIHJlYWRvbmx5KQorCQlzZWxmLndyYXAgPSB3cmFwCisJCisJZGVmIF9nZXRmbGFncyhzZWxmKToKKwkJZmxhZ3MgPSBXQVNURWNvbnN0LndlRG9BdXRvU2Nyb2xsIHwgV0FTVEVjb25zdC53ZURvTW9ub1N0eWxlZCB8IFwKKwkJCQlXQVNURWNvbnN0LndlRG9PdXRsaW5lSGlsaXRlCisJCWlmIHNlbGYucmVhZG9ubHk6CisJCQlmbGFncyA9IGZsYWdzIHwgV0FTVEVjb25zdC53ZURvUmVhZE9ubHkKKwkJZWxzZToKKwkJCWZsYWdzID0gZmxhZ3MgfCBXQVNURWNvbnN0LndlRG9VbmRvCisJCXJldHVybiBmbGFncworCQorCWRlZiBfZ2V0dmlld3JlY3Qoc2VsZik6CisJCWwsIHQsIHIsIGIgPSBzZWxmLl9ib3VuZHMKKwkJcmV0dXJuIChsICsgNSwgdCArIDIsIHIsIGIgLSAyKQorCQorCWRlZiBfY2FsY3RleHRib3VuZHMoc2VsZik6CisJCWlmIHNlbGYud3JhcDoKKwkJCXJldHVybiBFZGl0VGV4dC5fY2FsY3RleHRib3VuZHMoc2VsZikKKwkJZWxzZToKKwkJCXZpZXdyZWN0ID0gbCwgdCwgciwgYiA9IHNlbGYuX2dldHZpZXdyZWN0KCkKKwkJCWlmIHNlbGYudGVkOgorCQkJCWRsLCBkdCwgZHIsIGRiID0gc2VsZi50ZWQuV0VHZXREZXN0UmVjdCgpCisJCQkJdmwsIHZ0LCB2ciwgdmIgPSBzZWxmLnRlZC5XRUdldFZpZXdSZWN0KCkKKwkJCQl4c2hpZnQgPSBsIC0gdmwKKwkJCQl5c2hpZnQgPSB0IC0gdnQKKwkJCQlpZiAoZGIgLSBkdCkgPCAoYiAtIHQpOgorCQkJCQl5c2hpZnQgPSB0IC0gZHQKKwkJCQlkZXN0cmVjdCA9IChkbCArIHhzaGlmdCwgZHQgKyB5c2hpZnQsIGRyICsgeHNoaWZ0LCBkYiArIHlzaGlmdCkKKwkJCWVsc2U6CisJCQkJZGVzdHJlY3QgPSAobCwgdCwgciArIDUwMDAsIGIpCisJCQlyZXR1cm4gdmlld3JlY3QsIGRlc3RyZWN0CisJCisJZGVmIGRyYXcoc2VsZiwgdmlzUmduID0gTm9uZSk6CisJCWlmIHNlbGYuX3Zpc2libGU6CisJCQlpZiBub3QgdmlzUmduOgorCQkJCXZpc1JnbiA9IHNlbGYuX3BhcmVudHdpbmRvdy53aWQuR2V0V2luZG93UG9ydCgpLnZpc1JnbgorCQkJc2VsZi50ZWQuV0VVcGRhdGUodmlzUmduKQorCQkJaWYgc2VsZi5fc2VsZWN0ZWQgYW5kIHNlbGYuX2FjdGl2YXRlZDoKKwkJCQlzZWxmLmRyYXdzZWxmcmFtZSgxKQorCisKK2NsYXNzIFB5RWRpdG9yKFRleHRFZGl0b3IpOgorCQorCWRlZiBfX2luaXRfXyhzZWxmLCBwb3NzaXplLCB0ZXh0ID0gIiIsIGNhbGxiYWNrID0gTm9uZSwgaW5zZXQgPSAoNCwgNCksCisJCQkJZm9udHNldHRpbmdzID0gKCJQeXRob24tU2FucyIsIDAsIDksICgwLCAwLCAwKSksCisJCQkJcmVhZG9ubHkgPSAwLAorCQkJCWRlYnVnZ2VyID0gTm9uZSwKKwkJCQlmaWxlID0gJycpOgorCQlUZXh0RWRpdG9yLl9faW5pdF9fKHNlbGYsIHBvc3NpemUsIHRleHQsIGNhbGxiYWNrLCAwLCBpbnNldCwgZm9udHNldHRpbmdzLCByZWFkb25seSkKKwkJc2VsZi5iaW5kKCJjbWRbIiwgc2VsZi5zaGlmdGxlZnQpCisJCXNlbGYuYmluZCgiY21kXSIsIHNlbGYuc2hpZnRyaWdodCkKKwkJc2VsZi5maWxlID0gZmlsZQkjIG9ubHkgZm9yIGRlYnVnZ2VyIHJlZmVyZW5jZQorCQlzZWxmLl9kZWJ1Z2dlciA9IGRlYnVnZ2VyCisJCWlmIGRlYnVnZ2VyOgorCQkJZGVidWdnZXIucmVnaXN0ZXJfZWRpdG9yKHNlbGYsIHNlbGYuZmlsZSkKKwkKKwlkZWYgc2V0ZmlsZShzZWxmLCBmaWxlKToKKwkJc2VsZi5maWxlID0gZmlsZQorCQorCWRlZiBzZXQoc2VsZiwgdGV4dCwgZmlsZSA9ICcnKToKKwkJb2xkZmlsZSA9IHNlbGYuZmlsZQorCQlzZWxmLmZpbGUgPSBmaWxlCisJCWlmIHNlbGYuX2RlYnVnZ2VyOgorCQkJc2VsZi5fZGVidWdnZXIudW5yZWdpc3Rlcl9lZGl0b3Ioc2VsZiwgb2xkZmlsZSkKKwkJCXNlbGYuX2RlYnVnZ2VyLnJlZ2lzdGVyX2VkaXRvcihzZWxmLCBmaWxlKQorCQlUZXh0RWRpdG9yLnNldChzZWxmLCB0ZXh0KQorCQorCWRlZiBjbG9zZShzZWxmKToKKwkJaWYgc2VsZi5fZGVidWdnZXI6CisJCQlzZWxmLl9kZWJ1Z2dlci51bnJlZ2lzdGVyX2VkaXRvcihzZWxmLCBzZWxmLmZpbGUpCisJCQlzZWxmLl9kZWJ1Z2dlciA9IE5vbmUKKwkJVGV4dEVkaXRvci5jbG9zZShzZWxmKQkJCisJCisJZGVmIGNsaWNrKHNlbGYsIHBvaW50LCBtb2RpZmllcnMpOgorCQlpZiBub3Qgc2VsZi5fZW5hYmxlZDoKKwkJCXJldHVybgorCQlpZiBzZWxmLl9kZWJ1Z2dlciBhbmQgc2VsZi5wdF9pbl9icmVha3MocG9pbnQpOgorCQkJc2VsZi5icmVha2hpdChwb2ludCwgbW9kaWZpZXJzKQorCQllbGlmIHNlbGYuX2RlYnVnZ2VyOgorCQkJYmwsIGJ0LCBiciwgYmIgPSBzZWxmLl9nZXRicmVha3JlY3QoKQorCQkJUWQuRXJhc2VSZWN0KChibCwgYnQsIGJyLTEsIGJiKSkKKwkJCVRleHRFZGl0b3IuY2xpY2soc2VsZiwgcG9pbnQsIG1vZGlmaWVycykKKwkJCXNlbGYuZHJhd2JyZWFrcG9pbnRzKCkKKwkJZWxzZToKKwkJCVRleHRFZGl0b3IuY2xpY2soc2VsZiwgcG9pbnQsIG1vZGlmaWVycykKKwkJCWlmIHNlbGYudGVkLldFR2V0Q2xpY2tDb3VudCgpID49IDM6CisJCQkJIyBzZWxlY3QgYmxvY2sgd2l0aCBvdXIgaW5kZW50CisJCQkJbGluZXMgPSBzdHJpbmcuc3BsaXQoc2VsZi5nZXQoKSwgJ1xyJykKKwkJCQlzZWxzdGFydCwgc2VsZW5kID0gc2VsZi50ZWQuV0VHZXRTZWxlY3Rpb24oKQorCQkJCWxpbmVubyA9IHNlbGYudGVkLldFT2Zmc2V0VG9MaW5lKHNlbHN0YXJ0KQorCQkJCXRhYnMgPSAwCisJCQkJbGluZSA9IGxpbmVzW2xpbmVub10KKwkJCQl3aGlsZSBsaW5lW3RhYnM6XSBhbmQgbGluZVt0YWJzXSA9PSAnXHQnOgorCQkJCQl0YWJzID0gdGFicyArIDEKKwkJCQl0YWJzdGFnID0gJ1x0JyAqIHRhYnMKKwkJCQlmcm9tbGluZSA9IDAKKwkJCQl0b2xpbmUgPSBsZW4obGluZXMpCisJCQkJaWYgdGFiczoKKwkJCQkJZm9yIGkgaW4gcmFuZ2UobGluZW5vIC0gMSwgLTEsIC0xKToKKwkJCQkJCWxpbmUgPSBsaW5lc1tpXQorCQkJCQkJaWYgbGluZVs6dGFic10gPD4gdGFic3RhZzoKKwkJCQkJCQlmcm9tbGluZSA9IGkgKyAxCisJCQkJCQkJYnJlYWsKKwkJCQkJZm9yIGkgaW4gcmFuZ2UobGluZW5vICsgMSwgdG9saW5lKToKKwkJCQkJCWxpbmUgPSBsaW5lc1tpXQorCQkJCQkJaWYgbGluZVs6dGFic10gPD4gdGFic3RhZzoKKwkJCQkJCQl0b2xpbmUgPSBpIC0gMQorCQkJCQkJCWJyZWFrCisJCQkJc2Vsc3RhcnQsIGR1bW15ID0gc2VsZi50ZWQuV0VHZXRMaW5lUmFuZ2UoZnJvbWxpbmUpCisJCQkJZHVtbXksIHNlbGVuZCA9IHNlbGYudGVkLldFR2V0TGluZVJhbmdlKHRvbGluZSkKKwkJCQlzZWxmLnRlZC5XRVNldFNlbGVjdGlvbihzZWxzdGFydCwgc2VsZW5kKQorCQorCWRlZiBicmVha2hpdChzZWxmLCBwb2ludCwgbW9kaWZpZXJzKToKKwkJaWYgbm90IHNlbGYuZmlsZToKKwkJCXJldHVybgorCQlvZmZzZXQsIGVkZ2UgPSBzZWxmLnRlZC5XRUdldE9mZnNldChwb2ludCkKKwkJbGluZW5vID0gc2VsZi50ZWQuV0VPZmZzZXRUb0xpbmUob2Zmc2V0KSArIDEKKwkJaWYgZWRnZSA8IDA6CisJCQlzZWxmLl9kZWJ1Z2dlci5jbGVhcl9icmVha3NfYWJvdmUoc2VsZi5maWxlLCBsaW5lbm8pCisJCWVsc2U6CisJCQlzZWxmLl9kZWJ1Z2dlci5jbGVhcl9icmVha3NfYWJvdmUoc2VsZi5maWxlLCBzZWxmLmNvdW50bGluZXMoKSkKKwkJCXNlbGYuX2RlYnVnZ2VyLnRvZ2dsZV9icmVhayhzZWxmLmZpbGUsIGxpbmVubykKKwkKKwlkZWYga2V5KHNlbGYsIGNoYXIsIGV2ZW50KToKKwkJKHdoYXQsIG1lc3NhZ2UsIHdoZW4sIHdoZXJlLCBtb2RpZmllcnMpID0gZXZlbnQKKwkJaWYgbW9kaWZpZXJzICYgRXZlbnRzLmNtZEtleSBhbmQgbm90IGNoYXIgaW4gYXJyb3drZXlzOgorCQkJcmV0dXJuCisJCWlmIGNoYXIgPT0gJ1xyJzoKKwkJCXNlbHN0YXJ0LCBzZWxlbmQgPSBzZWxmLnRlZC5XRUdldFNlbGVjdGlvbigpCisJCQlzZWxzdGFydCwgc2VsZW5kID0gbWluKHNlbHN0YXJ0LCBzZWxlbmQpLCBtYXgoc2Vsc3RhcnQsIHNlbGVuZCkKKwkJCWxhc3RjaGFyID0gY2hyKHNlbGYudGVkLldFR2V0Q2hhcihzZWxzdGFydC0xKSkKKwkJCWlmIGxhc3RjaGFyIDw+ICdccicgYW5kIHNlbHN0YXJ0OgorCQkJCXBvcywgZHVtbXkgPSBzZWxmLnRlZC5XRUZpbmRMaW5lKHNlbHN0YXJ0LCAwKQorCQkJCWxpbmVyZXMgPSBSZXMuUmVzb3VyY2UoJycpCisJCQkJc2VsZi50ZWQuV0VDb3B5UmFuZ2UocG9zLCBzZWxzdGFydCwgbGluZXJlcywgTm9uZSwgTm9uZSkKKwkJCQlsaW5lID0gbGluZXJlcy5kYXRhICsgJ1xuJworCQkJCXRhYmNvdW50ID0gc2VsZi5leHRyYXRhYnMobGluZSkKKwkJCQlzZWxmLnRlZC5XRUtleShvcmQoJ1xyJyksIDApCisJCQkJZm9yIGkgaW4gcmFuZ2UodGFiY291bnQpOgorCQkJCQlzZWxmLnRlZC5XRUtleShvcmQoJ1x0JyksIDApCisJCQllbHNlOgorCQkJCXNlbGYudGVkLldFS2V5KG9yZCgnXHInKSwgMCkKKwkJZWxpZiBjaGFyIGluICcpXX0nOgorCQkJc2VsZi50ZWQuV0VLZXkob3JkKGNoYXIpLCBtb2RpZmllcnMpCisJCQlzZWxmLmJhbGFuY2VwYXJlbnMoY2hhcikKKwkJZWxzZToKKwkJCXNlbGYudGVkLldFS2V5KG9yZChjaGFyKSwgbW9kaWZpZXJzKQorCQlpZiBjaGFyIG5vdCBpbiBuYXZpZ2F0aW9ua2V5czoKKwkJCXNlbGYuY2hhbmdlZCA9IDEKKwkJc2VsZi5zZWxjaGFuZ2VkID0gMQorCQlzZWxmLnVwZGF0ZXNjcm9sbGJhcnMoKQorCQorCWRlZiBiYWxhbmNlcGFyZW5zKHNlbGYsIGNoYXIpOgorCQlpZiBjaGFyID09ICcpJzoKKwkJCXRhcmdldCA9ICcoJworCQllbGlmIGNoYXIgPT0gJ10nOgorCQkJdGFyZ2V0ID0gJ1snCisJCWVsaWYgY2hhciA9PSAnfSc6CisJCQl0YXJnZXQgPSAneycKKwkJcmVjdXJzaW9ubGV2ZWwgPSAxCisJCXNlbHN0YXJ0LCBzZWxlbmQgPSBzZWxmLnRlZC5XRUdldFNlbGVjdGlvbigpCisJCWNvdW50ID0gbWluKHNlbHN0YXJ0LCBzZWxlbmQpIC0gMgorCQltaW5jb3VudCA9IG1heCgwLCBjb3VudCAtIDIwNDgpCisJCWxhc3RxdW90ZSA9IE5vbmUKKwkJd2hpbGUgY291bnQgPiBtaW5jb3VudDoKKwkJCXRlc3RjaGFyID0gY2hyKHNlbGYudGVkLldFR2V0Q2hhcihjb3VudCkpCisJCQlpZiB0ZXN0Y2hhciBpbiAiXCInIiBhbmQgY2hyKHNlbGYudGVkLldFR2V0Q2hhcihjb3VudCAtIDEpKSA8PiAnXFwnOgorCQkJCWlmIGxhc3RxdW90ZSA9PSB0ZXN0Y2hhcjoKKwkJCQkJcmVjdXJzaW9ubGV2ZWwgPSByZWN1cnNpb25sZXZlbCAtIDEKKwkJCQkJbGFzdHF1b3RlID0gTm9uZQorCQkJCWVsaWYgbm90IGxhc3RxdW90ZToKKwkJCQkJcmVjdXJzaW9ubGV2ZWwgPSByZWN1cnNpb25sZXZlbCArIDEKKwkJCQkJbGFzdHF1b3RlID0gdGVzdGNoYXIKKwkJCWVsaWYgbm90IGxhc3RxdW90ZSBhbmQgdGVzdGNoYXIgPT0gY2hhcjoKKwkJCQlyZWN1cnNpb25sZXZlbCA9IHJlY3Vyc2lvbmxldmVsICsgMQorCQkJZWxpZiBub3QgbGFzdHF1b3RlIGFuZCB0ZXN0Y2hhciA9PSB0YXJnZXQ6CisJCQkJcmVjdXJzaW9ubGV2ZWwgPSByZWN1cnNpb25sZXZlbCAtIDEKKwkJCQlpZiByZWN1cnNpb25sZXZlbCA9PSAwOgorCQkJCQlpbXBvcnQgdGltZQorCQkJCQlhdXRvc2Nyb2xsID0gc2VsZi50ZWQuV0VGZWF0dXJlRmxhZyhXQVNURWNvbnN0LndlRkF1dG9TY3JvbGwsIC0xKQorCQkJCQlpZiBhdXRvc2Nyb2xsOgorCQkJCQkJc2VsZi50ZWQuV0VGZWF0dXJlRmxhZyhXQVNURWNvbnN0LndlRkF1dG9TY3JvbGwsIDApCisJCQkJCXNlbGYudGVkLldFU2V0U2VsZWN0aW9uKGNvdW50LCBjb3VudCArIDEpCisJCQkJCXRpbWUuc2xlZXAoMC4yKQorCQkJCQlzZWxmLnRlZC5XRVNldFNlbGVjdGlvbihzZWxzdGFydCwgc2VsZW5kKQorCQkJCQlpZiBhdXRvc2Nyb2xsOgorCQkJCQkJc2VsZi50ZWQuV0VGZWF0dXJlRmxhZyhXQVNURWNvbnN0LndlRkF1dG9TY3JvbGwsIDEpCisJCQkJCWJyZWFrCisJCQljb3VudCA9IGNvdW50IC0gMQorCQorCWRlZiBleHRyYXRhYnMoc2VsZiwgbGluZSk6CisJCXRhYmNvdW50ID0gMAorCQlmb3IgYyBpbiBsaW5lOgorCQkJaWYgYyA8PiAnXHQnOgorCQkJCWJyZWFrCisJCQl0YWJjb3VudCA9IHRhYmNvdW50ICsgMQorCQlsYXN0ID0gMAorCQljbGVhbmxpbmUgPSAnJworCQl0YWdzID0gUHlGb250aWZ5LmZvbnRpZnkobGluZSkKKwkJIyBzdHJpcCBjb21tZW50cyBhbmQgc3RyaW5ncworCQlmb3IgdGFnLCBzdGFydCwgZW5kLCBzdWJsaXN0IGluIHRhZ3M6CisJCQlpZiB0YWcgaW4gKCdzdHJpbmcnLCAnY29tbWVudCcpOgorCQkJCWNsZWFubGluZSA9IGNsZWFubGluZSArIGxpbmVbbGFzdDpzdGFydF0KKwkJCQlsYXN0ID0gZW5kCisJCWNsZWFubGluZSA9IGNsZWFubGluZSArIGxpbmVbbGFzdDpdCisJCWNsZWFubGluZSA9IHN0cmluZy5zdHJpcChjbGVhbmxpbmUpCisJCWlmIGNsZWFubGluZSBhbmQgY2xlYW5saW5lWy0xXSA9PSAnOic6CisJCQl0YWJjb3VudCA9IHRhYmNvdW50ICsgMQorCQllbHNlOgorCQkJZm9yIG9wZW4sIGNsb3NlIGluICgoJygnLCAnKScpLCAoJ1snLCAnXScpLCAoJ3snLCAnfScpKToKKwkJCQljb3VudCA9IHN0cmluZy5jb3VudChjbGVhbmxpbmUsIG9wZW4pCisJCQkJaWYgY291bnQgYW5kIGNvdW50IDw+IHN0cmluZy5jb3VudChjbGVhbmxpbmUsIGNsb3NlKToKKwkJCQkJdGFiY291bnQgPSB0YWJjb3VudCArIDIKKwkJCQkJYnJlYWsKKwkJcmV0dXJuIHRhYmNvdW50CisJCisJZGVmIHJvbGxvdmVyKHNlbGYsIHBvaW50LCBvbm9mZik6CisJCWlmIG9ub2ZmOgorCQkJaWYgc2VsZi5fZGVidWdnZXIgYW5kIHNlbGYucHRfaW5fYnJlYWtzKHBvaW50KToKKwkJCQlXYmFzZS5TZXRDdXJzb3IoImFycm93IikKKwkJCWVsc2U6CisJCQkJV2Jhc2UuU2V0Q3Vyc29yKCJpQmVhbSIpCisJCisJZGVmIGRyYXcoc2VsZiwgdmlzUmduID0gTm9uZSk6CisJCVRleHRFZGl0b3IuZHJhdyhzZWxmLCB2aXNSZ24pCisJCWlmIHNlbGYuX2RlYnVnZ2VyOgorCQkJc2VsZi5kcmF3YnJlYWtwb2ludHMoKQorCQorCWRlZiBzaG93YnJlYWtwb2ludHMoc2VsZiwgb25vZmYpOgorCQlpZiAobm90IG5vdCBzZWxmLl9kZWJ1Z2dlcikgPD4gb25vZmY6CisJCQlpZiBvbm9mZjoKKwkJCQlpbXBvcnQgUHlEZWJ1Z2dlcgorCQkJCXNlbGYuX2RlYnVnZ2VyID0gUHlEZWJ1Z2dlci5nZXRkZWJ1Z2dlcigpCisJCQkJc2VsZi5fZGVidWdnZXIucmVnaXN0ZXJfZWRpdG9yKHNlbGYsIHNlbGYuZmlsZSkKKwkJCWVsaWYgc2VsZi5fZGVidWdnZXI6CisJCQkJc2VsZi5fZGVidWdnZXIudW5yZWdpc3Rlcl9lZGl0b3Ioc2VsZiwgc2VsZi5maWxlKQorCQkJCXNlbGYuX2RlYnVnZ2VyID0gTm9uZQorCQkJc2VsZi5hZGp1c3Qoc2VsZi5fYm91bmRzKQorCQorCWRlZiB0b2dnbGVicmVha3BvaW50cyhzZWxmKToKKwkJc2VsZi5zaG93YnJlYWtwb2ludHMobm90IHNlbGYuX2RlYnVnZ2VyKQorCQorCWRlZiBjbGVhcmJyZWFrcG9pbnRzKHNlbGYpOgorCQlpZiBzZWxmLmZpbGU6CisJCQlzZWxmLl9kZWJ1Z2dlci5jbGVhcl9hbGxfZmlsZV9icmVha3Moc2VsZi5maWxlKQorCQorCWRlZiBlZGl0YnJlYWtwb2ludHMoc2VsZik6CisJCWlmIHNlbGYuX2RlYnVnZ2VyOgorCQkJc2VsZi5fZGVidWdnZXIuZWRpdF9icmVha3MoKQorCQkJc2VsZi5fZGVidWdnZXIuYnJlYWtzdmlld2VyLnNlbGVjdGZpbGUoc2VsZi5maWxlKQorCQorCWRlZiBkcmF3YnJlYWtwb2ludHMoc2VsZiwgZXJhc2VhbGwgPSAwKToKKwkJYnJlYWtyZWN0ID0gYmwsIGJ0LCBiciwgYmIgPSBzZWxmLl9nZXRicmVha3JlY3QoKQorCQliciA9IGJyIC0gMQorCQlzZWxmLlNldFBvcnQoKQorCQlRZC5QZW5QYXQoUWQucWQuZ3JheSkKKwkJUWQuUGFpbnRSZWN0KChiciwgYnQsIGJyICsgMSwgYmIpKQorCQlRZC5QZW5Ob3JtYWwoKQorCQlzZWxmLl9wYXJlbnR3aW5kb3cudGVtcGNsaXByZWN0KGJyZWFrcmVjdCkKKwkJUWQuUkdCRm9yZUNvbG9yKCgweGZmZmYsIDAsIDApKQorCQl0cnk6CisJCQlsYXN0dG9wID0gYnQKKwkJCXNlbGZfdGVkID0gc2VsZi50ZWQKKwkJCVFkX1BhaW50T3ZhbCA9IFFkLlBhaW50T3ZhbAorCQkJUWRfRXJhc2VSZWN0ID0gUWQuRXJhc2VSZWN0CisJCQlmb3IgbGluZW5vIGluIHNlbGYuX2RlYnVnZ2VyLmdldF9maWxlX2JyZWFrcyhzZWxmLmZpbGUpOgorCQkJCXN0YXJ0LCBlbmQgPSBzZWxmX3RlZC5XRUdldExpbmVSYW5nZShsaW5lbm8gLSAxKQorCQkJCWlmIGxpbmVubyA8PiBzZWxmX3RlZC5XRU9mZnNldFRvTGluZShzdGFydCkgKyAxOgorCQkJCQkjIGJyZWFrcG9pbnRzIGJleW9uZCBvdXIgdGV4dDogZXJhc2UgcmVzdCwgYW5kIGJhY2sgb3V0CisJCQkJCVFkX0VyYXNlUmVjdCgoYmwsIGxhc3R0b3AsIGJyLCBiYikpCisJCQkJCWJyZWFrCisJCQkJKHgsIHkpLCBoID0gc2VsZl90ZWQuV0VHZXRQb2ludChzdGFydCwgMCkKKwkJCQlib3R0b20gPSB5ICsgaAorCQkJCSNwcmludCB5LCAobGFzdHRvcCwgYm90dG9tKQorCQkJCWlmIGJvdHRvbSA+IGxhc3R0b3A6CisJCQkJCVFkX0VyYXNlUmVjdCgoYmwsIGxhc3R0b3AsIGJyLCB5ICsgaCAqIGVyYXNlYWxsKSkKKwkJCQkJbGFzdHRvcCA9IGJvdHRvbQorCQkJCXJlZGJ1bGxldCA9IGJsICsgMiwgeSArIDMsIGJsICsgOCwgeSArIDkKKwkJCQlRZF9QYWludE92YWwocmVkYnVsbGV0KQorCQkJZWxzZToKKwkJCQlRZF9FcmFzZVJlY3QoKGJsLCBsYXN0dG9wLCBiciwgYmIpKQorCQkJUWQuUkdCRm9yZUNvbG9yKCgwLCAwLCAwKSkKKwkJZmluYWxseToKKwkJCXNlbGYuX3BhcmVudHdpbmRvdy5yZXN0b3JlY2xpcCgpCisJCisJZGVmIHVwZGF0ZXNjcm9sbGJhcnMoc2VsZik6CisJCWlmIHNlbGYuX2RlYnVnZ2VyOgorCQkJc2VsZi5kcmF3YnJlYWtwb2ludHMoMSkKKwkJVGV4dEVkaXRvci51cGRhdGVzY3JvbGxiYXJzKHNlbGYpCisJCisJZGVmIHB0X2luX2JyZWFrcyhzZWxmLCBwb2ludCk6CisJCXJldHVybiBRZC5QdEluUmVjdChwb2ludCwgc2VsZi5fZ2V0YnJlYWtyZWN0KCkpCisJCisJZGVmIF9nZXRicmVha3JlY3Qoc2VsZik6CisJCWlmIHNlbGYuX2RlYnVnZ2VyOgorCQkJbCwgdCwgciwgYiA9IHNlbGYuX2JvdW5kcworCQkJcmV0dXJuIChsKzEsIHQrMSwgbCArIDEyLCBiLTEpCisJCWVsc2U6CisJCQlyZXR1cm4gKDAsIDAsIDAsIDApCisJCisJZGVmIF9nZXR2aWV3cmVjdChzZWxmKToKKwkJbCwgdCwgciwgYiA9IHNlbGYuX2JvdW5kcworCQlpZiBzZWxmLl9kZWJ1Z2dlcjoKKwkJCXJldHVybiAobCArIDE3LCB0ICsgMiwgciwgYiAtIDIpCisJCWVsc2U6CisJCQlyZXR1cm4gKGwgKyA1LCB0ICsgMiwgciwgYiAtIDIpCisJCisJZGVmIF9jYWxjdGV4dGJvdW5kcyhzZWxmKToKKwkJdmlld3JlY3QgPSBsLCB0LCByLCBiID0gc2VsZi5fZ2V0dmlld3JlY3QoKQorCQlpZiBzZWxmLnRlZDoKKwkJCWRsLCBkdCwgZHIsIGRiID0gc2VsZi50ZWQuV0VHZXREZXN0UmVjdCgpCisJCQl2bCwgdnQsIHZyLCB2YiA9IHNlbGYudGVkLldFR2V0Vmlld1JlY3QoKQorCQkJeHNoaWZ0ID0gbCAtIHZsCisJCQl5c2hpZnQgPSB0IC0gdnQKKwkJCWlmIChkYiAtIGR0KSA8IChiIC0gdCk6CisJCQkJeXNoaWZ0ID0gdCAtIGR0CisJCQlkZXN0cmVjdCA9IChkbCArIHhzaGlmdCwgZHQgKyB5c2hpZnQsIGRyICsgeHNoaWZ0LCBkYiArIHlzaGlmdCkKKwkJZWxzZToKKwkJCWRlc3RyZWN0ID0gKGwsIHQsIHIgKyA1MDAwLCBiKQorCQlyZXR1cm4gdmlld3JlY3QsIGRlc3RyZWN0CisKKworZGVmIEdldEZOdW0oZm9udCk6CisJaWYgZm9udCA8PiAnQ2hpY2Fnbyc6CisJCWZvbnRpZCA9IEZtLkdldEZOdW0oZm9udCkKKwkJaWYgZm9udGlkID09IDA6CisJCQlmb250aWQgPSBGb250cy5tb25hY28KKwllbHNlOgorCQlmb250aWQgPSAwCisJcmV0dXJuIGZvbnRpZAorCitkZWYgR2V0Rk5hbWUoZm9udGlkKToKKwl0cnk6CisJCXJlcyA9IFJlcy5HZXRSZXNvdXJjZSgnRk9ORCcsIGZvbnRpZCkKKwlleGNlcHQgUmVzLkVycm9yOgorCQlmb250bmFtZSA9ICdNb25hY28nCisJZWxzZToKKwkJZm9udG5hbWUgPSByZXMuR2V0UmVzSW5mbygpWzJdCisJcmV0dXJuIGZvbnRuYW1lCmRpZmYgLS1naXQgYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvV3RyYWNlYmFjay5weSBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9XdHJhY2ViYWNrLnB5Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjU4MDRjZDcKLS0tIC9kZXYvbnVsbAorKysgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvSURFTGliL1dpZGdldHMvV3RyYWNlYmFjay5weQpAQCAtMCwwICsxLDE5NiBAQAoraW1wb3J0IHRyYWNlYmFjaworaW1wb3J0IHN5cworaW1wb3J0IFcKK2ltcG9ydCBvcworaW1wb3J0IHR5cGVzCisKK2NsYXNzIFRyYWNlTGlzdChXLkxpc3QpOgorCQorCUxERUZfSUQgPSA0NjgKKwkKKwlkZWYgY3JlYXRlbGlzdChzZWxmKToKKwkJaW1wb3J0IExpc3QKKwkJc2VsZi5fY2FsY2JvdW5kcygpCisJCXNlbGYuU2V0UG9ydCgpCisJCXJlY3QgPSBzZWxmLl9ib3VuZHMKKwkJcmVjdCA9IHJlY3RbMF0rMSwgcmVjdFsxXSsxLCByZWN0WzJdLTE2LCByZWN0WzNdLTEKKwkJc2VsZi5fbGlzdCA9IExpc3QuTE5ldyhyZWN0LCAoMCwgMCwgMSwgMCksICgwLCAyOCksIHNlbGYuTERFRl9JRCwgc2VsZi5fcGFyZW50d2luZG93LndpZCwKKwkJCQkJMCwgMSwgMCwgMSkKKwkJc2VsZi5zZXQoc2VsZi5pdGVtcykKKwkKKworY2xhc3MgVHJhY2VCYWNrOgorCQorCWRlZiBfX2luaXRfXyhzZWxmLCB0aXRsZSA9ICJUcmFjZWJhY2siKToKKwkJYXBwID0gVy5nZXRhcHBsaWNhdGlvbigpICAjIGNoZWNrcyBpZiBXIGlzIHByb3Blcmx5IGluaXRpYWxpemVkCisJCXNlbGYudGl0bGUgPSB0aXRsZQorCQlzZWxmLncgPSBOb25lCisJCXNlbGYuY2xvc2VkID0gMQorCQlzZWxmLnN0YXJ0ID0gMAorCQlzZWxmLmxhc3R3aW5kb3d0aXRsZSA9ICIiCisJCXNlbGYuYm91bmRzID0gKDM2MCwgMjk4KQorCQorCWRlZiB0cmFjZWJhY2soc2VsZiwgc3RhcnQgPSAwLCBsYXN0d2luZG93dGl0bGUgPSAiIik6CisJCXRyeToKKwkJCXNlbGYubGFzdHdpbmRvd3RpdGxlID0gbGFzdHdpbmRvd3RpdGxlCisJCQlzZWxmLnN0YXJ0ID0gc3RhcnQKKwkJCXNlbGYudHlwZSwgc2VsZi52YWx1ZSwgc2VsZi50YiA9IHN5cy5leGNfdHlwZSwgc3lzLmV4Y192YWx1ZSwgc3lzLmV4Y190cmFjZWJhY2sKKwkJCWlmIHNlbGYudHlwZSBpcyBub3QgU3ludGF4RXJyb3I6CisJCQkJc2VsZi5zaG93KCkKKwkJCQlpZiB0eXBlKHNlbGYudHlwZSkgPT0gdHlwZXMuQ2xhc3NUeXBlOgorCQkJCQllcnJvcnRleHQgPSBzZWxmLnR5cGUuX19uYW1lX18KKwkJCQllbHNlOgorCQkJCQllcnJvcnRleHQgPSBzdHIoc2VsZi50eXBlKQorCQkJCXZhbHVlID0gc3RyKHNlbGYudmFsdWUpCisJCQkJaWYgc2VsZi52YWx1ZSBhbmQgdmFsdWU6CisJCQkJCWVycm9ydGV4dCA9IGVycm9ydGV4dCArICI6ICIgKyB2YWx1ZQorCQkJCXNlbGYudy50ZXh0LnNldChlcnJvcnRleHQpCisJCQkJc2VsZi5idWlsZHRibGlzdCgpCisJCQkJc2VsZi53Lmxpc3Quc2V0KHNlbGYudGV4dGxpc3QpCisJCQkJc2VsZi53Lmxpc3Quc2V0c2VsZWN0aW9uKFtsZW4oc2VsZi50ZXh0bGlzdCkgLSAxXSkKKwkJCQlzZWxmLncud2lkLlNlbGVjdFdpbmRvdygpCisJCQkJc2VsZi5jbG9zZWQgPSAwCisJCQllbHNlOgorCQkJCXNlbGYuc3ludGF4ZXJyb3IoKQorCQlleGNlcHQ6CisJCQl0cmFjZWJhY2sucHJpbnRfZXhjKCkKKwkKKwlkZWYgc3ludGF4ZXJyb3Ioc2VsZik6CisJCXRyeToKKwkJCXZhbHVlLCAoZmlsZW5hbWUsIGxpbmVubywgY2hhcm5vLCBsaW5lKSA9IHNlbGYudmFsdWUKKwkJZXhjZXB0OgorCQkJZmlsZW5hbWUgPSAiIgorCQkJbGluZW5vID0gTm9uZQorCQkJdmFsdWUgPSBzZWxmLnZhbHVlCisJCWlmIG5vdCBmaWxlbmFtZSBhbmQgc2VsZi5sYXN0d2luZG93dGl0bGU6CisJCQlmaWxlbmFtZSA9IHNlbGYubGFzdHdpbmRvd3RpdGxlCisJCWVsaWYgbm90IGZpbGVuYW1lOgorCQkJZmlsZW5hbWUgPSAiPHVua25vd24+IgorCQlpZiBmaWxlbmFtZSBhbmQgb3MucGF0aC5leGlzdHMoZmlsZW5hbWUpOgorCQkJZmlsZW5hbWUgPSBvcy5wYXRoLnNwbGl0KGZpbGVuYW1lKVsxXQorCQlpZiBsaW5lbm86CisJCQljaGFybm8gPSBjaGFybm8gLSAxCisJCQl0ZXh0ID0gdmFsdWUgKyAnXHJGaWxlOiAiJyArIHN0cihmaWxlbmFtZSkgKyAnIiwgbGluZSAnICsgc3RyKGxpbmVubykgKyAnXHJccicgKyBsaW5lWzpjaGFybm9dICsgIoAiICsgbGluZVtjaGFybm86LTFdCisJCWVsc2U6CisJCQl0ZXh0ID0gdmFsdWUgKyAnXHJGaWxlOiAiJyArIHN0cihmaWxlbmFtZSkgKyAnIicKKwkJc2VsZi5zeW50YXhkaWFsb2cgPSBXLk1vZGFsRGlhbG9nKCgzNjAsIDEyMCksICJTeW50YXggRXJyb3IiKQorCQlzZWxmLnN5bnRheGRpYWxvZy50ZXh0ID0gVy5UZXh0Qm94KCgxMCwgMTAsIC0xMCwgLTQwKSwgdGV4dCkKKwkJc2VsZi5zeW50YXhkaWFsb2cuY2FuY2VsID0gVy5CdXR0b24oKC0xOTAsIC0zMiwgODAsIDE2KSwgIkNhbmNlbCIsIHNlbGYuc3ludGF4Y2xvc2UpCisJCXNlbGYuc3ludGF4ZGlhbG9nLmVkaXQgPSBXLkJ1dHRvbigoLTEwMCwgLTMyLCA4MCwgMTYpLCAiRWRpdCIsIHNlbGYuc3ludGF4ZWRpdCkKKwkJc2VsZi5zeW50YXhkaWFsb2cuc2V0ZGVmYXVsdGJ1dHRvbihzZWxmLnN5bnRheGRpYWxvZy5lZGl0KQorCQlzZWxmLnN5bnRheGRpYWxvZy5iaW5kKCJjbWQuIiwgc2VsZi5zeW50YXhkaWFsb2cuY2FuY2VsLnB1c2gpCisJCXNlbGYuc3ludGF4ZGlhbG9nLm9wZW4oKQorCQorCWRlZiBzeW50YXhjbG9zZShzZWxmKToKKwkJc2VsZi5zeW50YXhkaWFsb2cuY2xvc2UoKQorCQlkZWwgc2VsZi5zeW50YXhkaWFsb2cKKwkKKwlkZWYgc3ludGF4ZWRpdChzZWxmKToKKwkJdHJ5OgorCQkJdmFsdWUsIChmaWxlbmFtZSwgbGluZW5vLCBjaGFybm8sIGxpbmUpID0gc2VsZi52YWx1ZQorCQlleGNlcHQ6CisJCQlmaWxlbmFtZSA9ICIiCisJCQlsaW5lbm8gPSBOb25lCisJCWlmIG5vdCBmaWxlbmFtZSBhbmQgc2VsZi5sYXN0d2luZG93dGl0bGU6CisJCQlmaWxlbmFtZSA9IHNlbGYubGFzdHdpbmRvd3RpdGxlCisJCWVsaWYgbm90IGZpbGVuYW1lOgorCQkJZmlsZW5hbWUgPSAiPHVua25vd24+IgorCQlzZWxmLnN5bnRheGNsb3NlKCkKKwkJaWYgbGluZW5vOgorCQkJVy5nZXRhcHBsaWNhdGlvbigpLm9wZW5zY3JpcHQoZmlsZW5hbWUsIGxpbmVubywgY2hhcm5vIC0gMSkKKwkJZWxzZToKKwkJCVcuZ2V0YXBwbGljYXRpb24oKS5vcGVuc2NyaXB0KGZpbGVuYW1lKQorCQorCWRlZiBzaG93KHNlbGYpOgorCQlpZiBzZWxmLmNsb3NlZDoKKwkJCXNlbGYuc2V0dXB3aWRnZXRzKCkKKwkJCXNlbGYudy5vcGVuKCkKKwkJZWxzZToKKwkJCXNlbGYudy53aWQuU2hvd1dpbmRvdygpCisJCQlzZWxmLncud2lkLlNlbGVjdFdpbmRvdygpCisJCisJZGVmIGNsb3NlKHNlbGYpOgorCQlzZWxmLmJvdW5kcyA9IHNlbGYudy5nZXRib3VuZHMoKQorCQlzZWxmLmNsb3NlZCA9IDEKKwkJc2VsZi50eXBlLCBzZWxmLnZhbHVlLCBzZWxmLnRiID0gTm9uZSwgTm9uZSwgTm9uZQorCQlzZWxmLnRibGlzdCA9IE5vbmUKKwkKKwlkZWYgYWN0aXZhdGUoc2VsZiwgb25vZmYpOgorCQlpZiBvbm9mZjoKKwkJCWlmIHNlbGYuY2xvc2VkOgorCQkJCXNlbGYudHJhY2ViYWNrKCkKKwkJCXNlbGYuY2xvc2VkID0gMAorCQkJc2VsZi5jaGVja2J1dHRvbnMoKQorCQorCWRlZiBzZXR1cHdpZGdldHMoc2VsZik6CisJCXNlbGYudyA9IFcuV2luZG93KHNlbGYuYm91bmRzLCBzZWxmLnRpdGxlLCBtaW5zaXplID0gKDMxNiwgMTY4KSkKKwkJc2VsZi53LnRleHQgPSBXLlRleHRCb3goKDEwLCAxMCwgLTEwLCAzMCkpCisJCXNlbGYudy50YnRpdGxlID0gVy5UZXh0Qm94KCgxMCwgNDAsIC0xMCwgMTApLCAiVHJhY2ViYWNrIChpbm5lcm1vc3QgbGFzdCk6IikKKwkJc2VsZi53Lmxpc3QgPSBUcmFjZUxpc3QoKDEwLCA2MCwgLTEwLCAtNDApLCBjYWxsYmFjayA9IHNlbGYubGlzdGhpdCkKKwkJCisJCXNlbGYudy5lZGl0YnV0dG9uID0gVy5CdXR0b24oKDEwLCAtMzAsIDYwLCAxNiksICJFZGl0Iiwgc2VsZi5lZGl0KQorCQlzZWxmLncuZWRpdGJ1dHRvbi5lbmFibGUoMCkKKwkJCisJCXNlbGYudy5icm93c2Vsb2NhbHNidXR0b24gPSBXLkJ1dHRvbigoODAsIC0zMCwgMTAwLCAxNiksICJCcm93c2UgbG9jYWxziiIsIHNlbGYuYnJvd3NlbG9jYWxzKQorCQlzZWxmLncuYnJvd3NlbG9jYWxzYnV0dG9uLmVuYWJsZSgwKQorCQkKKwkJc2VsZi53LnBvc3Rtb3J0ZW1idXR0b24gPSBXLkJ1dHRvbigoMTkwLCAtMzAsIDEwMCwgMTYpLCAiUG9zdCBtb3J0ZW2KIiwgc2VsZi5wb3N0bW9ydGVtKQorCQkKKwkJc2VsZi53LnNldGRlZmF1bHRidXR0b24oc2VsZi53LmVkaXRidXR0b24pCisJCXNlbGYudy5iaW5kKCJjbWRiIiwgc2VsZi53LmJyb3dzZWxvY2Fsc2J1dHRvbi5wdXNoKQorCQlzZWxmLncuYmluZCgiPGNsb3NlPiIsIHNlbGYuY2xvc2UpCisJCXNlbGYudy5iaW5kKCI8YWN0aXZhdGU+Iiwgc2VsZi5hY3RpdmF0ZSkKKwkKKwlkZWYgYnVpbGR0Ymxpc3Qoc2VsZik6CisJCXRiID0gc2VsZi50YgorCQlmb3IgaSBpbiByYW5nZShzZWxmLnN0YXJ0KToKKwkJCWlmIHRiLnRiX25leHQgaXMgTm9uZToKKwkJCQlicmVhaworCQkJdGIgPSB0Yi50Yl9uZXh0CisJCXNlbGYudGJsaXN0ID0gdHJhY2ViYWNrLmV4dHJhY3RfdGIodGIpCisJCXNlbGYudGV4dGxpc3QgPSBbXQorCQlmb3IgZmlsZW5hbWUsIGxpbmVubywgZnVuYywgbGluZSBpbiBzZWxmLnRibGlzdDoKKwkJCXRibGluZSA9ICIiCisJCQlpZiBvcy5wYXRoLmV4aXN0cyhmaWxlbmFtZSk6CisJCQkJZmlsZW5hbWUgPSBvcy5wYXRoLnNwbGl0KGZpbGVuYW1lKVsxXQorCQkJCXRibGluZSA9ICdGaWxlICInICsgZmlsZW5hbWUgKyAnIiwgbGluZSAnICsgYGxpbmVub2AgKyAnLCBpbiAnICsgZnVuYworCQkJZWxzZToKKwkJCQl0YmxpbmUgPSAnRmlsZSAiJyArIGZpbGVuYW1lICsgJyIsIGxpbmUgJyArIGBsaW5lbm9gICsgJywgaW4gJyArIGZ1bmMKKwkJCWlmIGxpbmU6CisJCQkJdGJsaW5lID0gdGJsaW5lICsgJ1xyICAgICAgJyArIGxpbmUKKwkJCXNlbGYudGV4dGxpc3QuYXBwZW5kKHRibGluZVs6MjU1XSkKKwkKKwlkZWYgZWRpdChzZWxmKToKKwkJc2VsID0gc2VsZi53Lmxpc3QuZ2V0c2VsZWN0aW9uKCkKKwkJZm9yIGkgaW4gc2VsOgorCQkJZmlsZW5hbWUsIGxpbmVubywgZnVuYywgbGluZSA9IHNlbGYudGJsaXN0W2ldCisJCQlXLmdldGFwcGxpY2F0aW9uKCkub3BlbnNjcmlwdChmaWxlbmFtZSwgbGluZW5vKQorCQorCWRlZiBicm93c2Vsb2NhbHMoc2VsZik6CisJCXNlbCA9IHNlbGYudy5saXN0LmdldHNlbGVjdGlvbigpCisJCWZvciBpIGluIHNlbDoKKwkJCXRiID0gc2VsZi50YgorCQkJZm9yIGogaW4gcmFuZ2UoaSArIHNlbGYuc3RhcnQpOgorCQkJCXRiID0gdGIudGJfbmV4dAorCQkJc2VsZi5icm93c2UodGIudGJfZnJhbWUuZl9sb2NhbHMpCisJCisJZGVmIGJyb3dzZShzZWxmLCBvYmplY3QpOgorCQlpbXBvcnQgUHlCcm93c2VyCisJCVB5QnJvd3Nlci5Ccm93c2VyKG9iamVjdCkKKwkKKwlkZWYgcG9zdG1vcnRlbShzZWxmKToKKwkJaW1wb3J0IFB5RGVidWdnZXIKKwkJUHlEZWJ1Z2dlci5wb3N0bW9ydGVtKHNlbGYudHlwZSwgc2VsZi52YWx1ZSwgc2VsZi50YikKKwkKKwlkZWYgbGlzdGhpdChzZWxmLCBpc2RibCk6CisJCWlmIGlzZGJsOgorCQkJc2VsZi53LmVkaXRidXR0b24ucHVzaCgpCisJCWVsc2U6CisJCQlzZWxmLmNoZWNrYnV0dG9ucygpCisJCisJZGVmIGNoZWNrYnV0dG9ucyhzZWxmKToKKwkJaGF2ZWZpbGUgPSBsZW4oc2VsZi53Lmxpc3QuZ2V0c2VsZWN0aW9uKCkpID4gMAorCQlzZWxmLncuZWRpdGJ1dHRvbi5lbmFibGUoaGF2ZWZpbGUpCisJCXNlbGYudy5icm93c2Vsb2NhbHNidXR0b24uZW5hYmxlKGhhdmVmaWxlKQorCQlzZWxmLncuc2V0ZGVmYXVsdGJ1dHRvbihoYXZlZmlsZSBhbmQgc2VsZi53LmVkaXRidXR0b24gb3Igc2VsZi53LnBvc3Rtb3J0ZW1idXR0b24pCisKZGlmZiAtLWdpdCBhL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9Xd2luZG93cy5weSBiL01hYy9Db250cmliL1B5SURFLXNyYy9JREVMaWIvV2lkZ2V0cy9Xd2luZG93cy5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5jNDg4ODEwCi0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL0lERUxpYi9XaWRnZXRzL1d3aW5kb3dzLnB5CkBAIC0wLDAgKzEsNTc4IEBACitpbXBvcnQgUWQKK2ltcG9ydCBXaW4KK2ltcG9ydCBFdnQKK2ltcG9ydCBGbQoraW1wb3J0IEZyYW1lV29yaworaW1wb3J0IFdpbmRvd3MKK2ltcG9ydCBFdmVudHMKK2ltcG9ydCBXYmFzZQoraW1wb3J0IFdsaXN0CitpbXBvcnQgRGxnCitpbXBvcnQgTWFjT1MKK2ltcG9ydCBNZW51CitpbXBvcnQgc3RydWN0CisKK2Zyb20gdHlwZXMgaW1wb3J0ICoKK2Zyb20gU3BlY2lhbEtleXMgaW1wb3J0ICoKKworCitjbGFzcyBXaW5kb3coRnJhbWVXb3JrLldpbmRvdywgV2Jhc2UuU2VsZWN0YWJsZVdpZGdldCk6CisJCisJd2luZG93a2luZCA9IFdpbmRvd3MuZG9jdW1lbnRQcm9jCisJCisJZGVmIF9faW5pdF9fKHNlbGYsIHBvc3NpemUsIHRpdGxlID0gIiIsIG1pbnNpemUgPSBOb25lLCBtYXhzaXplID0gTm9uZSwgdGFiYmFibGUgPSAxLCBzaG93ID0gMSk6CisJCVdiYXNlLlNlbGVjdGFibGVXaWRnZXQuX19pbml0X18oc2VsZiwgcG9zc2l6ZSkKKwkJc2VsZi5fZ2xvYmFsYm91bmRzID0gbCwgdCwgciwgYiA9IHNlbGYuZ2V0d2luZG93Ym91bmRzKHBvc3NpemUsIG1pbnNpemUpCisJCXNlbGYuX2JvdW5kcyA9ICgwLCAwLCByIC0gbCwgYiAtIHQpCisJCXNlbGYuX3RhYmNoYWluID0gW10KKwkJc2VsZi5fY3VycmVudHdpZGdldCA9IE5vbmUKKwkJc2VsZi50aXRsZSA9IHRpdGxlCisJCXNlbGYuX3BhcmVudHdpbmRvdyA9IHNlbGYKKwkJc2VsZi5fdGFiYmFibGUgPSB0YWJiYWJsZQorCQlzZWxmLl9kZWZhdWx0YnV0dG9uID0gTm9uZQorCQlzZWxmLl9kcmF3d2lkZ2V0Ym91bmRzID0gMAorCQlzZWxmLl9zaG93ID0gc2hvdworCQlzZWxmLl9sYXN0cm9sbG92ZXIgPSBOb25lCisJCWlmIG1pbnNpemU6CisJCQlzZWxmLl9oYXNncm93Ym94ID0gMQorCQkJc2VsZi53aW5kb3draW5kID0gc2VsZi53aW5kb3draW5kIHwgOAorCQkJbCwgdCA9IG1pbnNpemUKKwkJCWlmIG1heHNpemU6CisJCQkJciwgYiA9IG1heHNpemVbMF0gKyAxLCBtYXhzaXplWzFdICsgMQorCQkJZWxzZToKKwkJCQlyLCBiID0gMzIwMDAsIDMyMDAwCisJCQlzZWxmLmdyb3dsaW1pdCA9IChsLCB0LCByLCBiKQorCQllbHNlOgorCQkJc2VsZi5faGFzZ3Jvd2JveCA9IDAKKwkJCWlmIHNlbGYud2luZG93a2luZCA9PSAwIG9yIHNlbGYud2luZG93a2luZCA+PTg6CisJCQkJc2VsZi53aW5kb3draW5kID0gc2VsZi53aW5kb3draW5kIHwgNAorCQlpbXBvcnQgVworCQlpZiBub3QgVy5fYXBwbGljYXRpb246CisJCQlyYWlzZSBXLldpZGdldHNFcnJvciwgJ1cgbm90IHByb3Blcmx5IGluaXRpYWxpemVkOiB1bmtub3duIEFwcGxpY2F0aW9uJworCQlGcmFtZVdvcmsuV2luZG93Ll9faW5pdF9fKHNlbGYsIFcuX2FwcGxpY2F0aW9uKQorCQorCWRlZiBnZXR0aXRsZShzZWxmKToKKwkJcmV0dXJuIHNlbGYudGl0bGUKKwkKKwlkZWYgc2V0dGl0bGUoc2VsZiwgdGl0bGUpOgorCQlzZWxmLnRpdGxlID0gdGl0bGUKKwkJaWYgc2VsZi53aWQ6CisJCQlzZWxmLndpZC5TZXRXVGl0bGUodGl0bGUpCisJCisJZGVmIGdldHdpbmRvd2JvdW5kcyhzZWxmLCBzaXplLCBtaW5zaXplID0gTm9uZSk6CisJCXJldHVybiB3aW5kb3dib3VuZHMoc2l6ZSwgbWluc2l6ZSkJCisJCisJZGVmIGdldGN1cnJlbnR3aWRnZXQoc2VsZik6CisJCXJldHVybiBzZWxmLl9jdXJyZW50d2lkZ2V0CisJCisJZGVmIHNob3coc2VsZiwgb25vZmYpOgorCQlpZiBvbm9mZjoKKwkJCXNlbGYud2lkLlNob3dXaW5kb3coKQorCQllbHNlOgorCQkJc2VsZi53aWQuSGlkZVdpbmRvdygpCisJCisJZGVmIGlzdmlzaWJsZShzZWxmKToKKwkJcmV0dXJuIHNlbGYud2lkLklzV2luZG93VmlzaWJsZSgpCisJCisJZGVmIGdldGJvdW5kcyhzZWxmKToKKwkJaWYgMDoJI3NlbGYuaXN2aXNpYmxlKCk6CisJCQlzZWxmLndpZC5HZXRXaW5kb3dDb250ZW50UmduKHNjcmF0Y2hSZWdpb24pCisJCQlzZWxmLl9nbG9iYWxib3VuZHMgPSBHZXRSZ25Cb3VuZHMoc2NyYXRjaFJlZ2lvbikKKwkJcmV0dXJuIHNlbGYuX2dsb2JhbGJvdW5kcworCQkKKwlkZWYgc2VsZWN0KHNlbGYpOgorCQlzZWxmLndpZC5TZWxlY3RXaW5kb3coKQorCQorCWRlZiBvcGVuKHNlbGYpOgorCQlzZWxmLndpZCA9IFdpbi5OZXdDV2luZG93KHNlbGYuX2dsb2JhbGJvdW5kcywgc2VsZi50aXRsZSwgc2VsZi5fc2hvdywKKwkJCXNlbGYud2luZG93a2luZCwgLTEsIDEsIDApCisJCXNlbGYuU2V0UG9ydCgpCisJCWZudW0gPSBGbS5HZXRGTnVtKCJQeXRob24tU2FucyIpCisJCWlmIGZudW0gPT0gMDoKKwkJCWZudW0gPSBGbS5HZXRGTnVtKCJHZW5ldmEiKQorCQlRZC5UZXh0Rm9udChmbnVtKQkjIFhYWCBmb250JnNpemUgZnJvbSBhIGZ1bmN0aW9uPworCQlRZC5UZXh0U2l6ZSg5KQkjIFhYWCBmb250JnNpemUgZnJvbSBhIGZ1bmN0aW9uPworCQlpZiBzZWxmLl9iaW5kaW5ncy5oYXNfa2V5KCI8b3Blbj4iKToKKwkJCWNhbGxiYWNrID0gc2VsZi5fYmluZGluZ3NbIjxvcGVuPiJdCisJCQljYWxsYmFjaygpCisJCWZvciB3IGluIHNlbGYuX3dpZGdldHM6CisJCQl3LmZvcmFsbF9mcm9tYm90dG9tKCJvcGVuIikKKwkJc2VsZi5fbWFrZXRhYmNoYWluKCkKKwkJaWYgc2VsZi5fdGFiY2hhaW46CisJCQlzZWxmLl90YWJjaGFpblswXS5zZWxlY3QoMSkKKwkJaWYgc2VsZi5fdGFiYmFibGU6CisJCQlzZWxmLmJpbmQoJ3RhYicsIHNlbGYubmV4dHdpZGdldCkKKwkJCXNlbGYuYmluZCgnc2hpZnR0YWInLCBzZWxmLnByZXZpb3Vzd2lkZ2V0KQorCQlzZWxmLmRvX3Bvc3RvcGVuKCkKKwkKKwlkZWYgY2xvc2Uoc2VsZik6CisJCWlmIG5vdCBzZWxmLndpZDoKKwkJCXJldHVybgkjIHdlIGFyZSBhbHJlYWR5IGNsb3NlZAorCQlpZiBzZWxmLl9iaW5kaW5ncy5oYXNfa2V5KCI8Y2xvc2U+Iik6CisJCQljYWxsYmFjayA9IHNlbGYuX2JpbmRpbmdzWyI8Y2xvc2U+Il0KKwkJCXJ2ID0gY2FsbGJhY2soKQorCQkJaWYgcnY6CisJCQkJcmV0dXJuIHJ2CisJCSNmb3Iga2V5IGluIHNlbGYuX3dpZGdldHNkaWN0LmtleXMoKToKKwkJIwlzZWxmLl9yZW1vdmV3aWRnZXQoa2V5KQorCQlzZWxmLmZvcmFsbF9idXRzZWxmKCJjbG9zZSIpCisJCVdiYXNlLlNlbGVjdGFibGVXaWRnZXQuY2xvc2Uoc2VsZikKKwkJc2VsZi5fdGFiY2hhaW4gPSBbXQorCQlzZWxmLl9jdXJyZW50d2lkZ2V0ID0gTm9uZQorCQlzZWxmLndpZC5IaWRlV2luZG93KCkKKwkJc2VsZi5kb19wb3N0Y2xvc2UoKQorCQorCWRlZiBkb21lbnVfY2xvc2Uoc2VsZiwgKmFyZ3MpOgorCQlzZWxmLmNsb3NlKCkKKwkKKwlkZWYgbW92ZShzZWxmLCB4LCB5ID0gTm9uZSk6CisJCSIiImFic29sdXRlIG1vdmUiIiIKKwkJaWYgeSA9PSBOb25lOgorCQkJeCwgeSA9IHgKKwkJc2VsZi53aWQuTW92ZVdpbmRvdyh4LCB5LCAwKQorCQorCWRlZiByZXNpemUoc2VsZiwgeCwgeSA9IE5vbmUpOgorCQlpZiB5ID09IE5vbmU6CisJCQl4LCB5ID0geAorCQlpZiBzZWxmLl9oYXNncm93Ym94OgorCQkJc2VsZi5TZXRQb3J0KCkKKwkJCVdpbi5JbnZhbFJlY3Qoc2VsZi5nZXRncm93cmVjdCgpKQorCQlzZWxmLndpZC5TaXplV2luZG93KHgsIHksIDEpCisJCXNlbGYuX2NhbGNib3VuZHMoKQorCQorCWRlZiB0ZXN0KHNlbGYsIHBvaW50KToKKwkJcmV0dXJuIDEKKwkKKwlkZWYgZHJhdyhzZWxmLCB2aXNSZ24gPSBOb25lKToKKwkJaWYgc2VsZi5faGFzZ3Jvd2JveDoKKwkJCXNlbGYudGVtcGNsaXByZWN0KHNlbGYuZ2V0Z3Jvd3JlY3QoKSkKKwkJCXNlbGYud2lkLkRyYXdHcm93SWNvbigpCisJCQlzZWxmLnJlc3RvcmVjbGlwKCkKKwkKKwlkZWYgaWRsZShzZWxmLCAqYXJncyk6CisJCXNlbGYuU2V0UG9ydCgpCisJCXBvaW50ID0gRXZ0LkdldE1vdXNlKCkKKwkJd2lkZ2V0ID0gc2VsZi5maW5kd2lkZ2V0KHBvaW50LCAwKQorCQlpZiB3aWRnZXQgaXMgbm90IE5vbmUgYW5kIGhhc2F0dHIod2lkZ2V0LCAicm9sbG92ZXIiKToKKwkJCWlmIDE6CSNzZWxmLl9sYXN0cm9sbG92ZXIgPD4gd2lkZ2V0OgorCQkJCWlmIHNlbGYuX2xhc3Ryb2xsb3ZlcjoKKwkJCQkJc2VsZi5fbGFzdHJvbGxvdmVyLnJvbGxvdmVyKHBvaW50LCAwKQorCQkJCXNlbGYuX2xhc3Ryb2xsb3ZlciA9IHdpZGdldAorCQkJCXNlbGYuX2xhc3Ryb2xsb3Zlci5yb2xsb3Zlcihwb2ludCwgMSkKKwkJZWxzZToKKwkJCWlmIHNlbGYuX2xhc3Ryb2xsb3ZlcjoKKwkJCQlzZWxmLl9sYXN0cm9sbG92ZXIucm9sbG92ZXIocG9pbnQsIDApCisJCQlzZWxmLl9sYXN0cm9sbG92ZXIgPSBOb25lCisJCQlXYmFzZS5TZXRDdXJzb3IoImFycm93IikKKwkJaWYgc2VsZi5fYmluZGluZ3MuaGFzX2tleSgiPGlkbGU+Iik6CisJCQljYWxsYmFjayA9IHNlbGYuX2JpbmRpbmdzWyI8aWRsZT4iXQorCQkJaWYgY2FsbGJhY2soKToKKwkJCQlyZXR1cm4KKwkJaWYgc2VsZi5fY3VycmVudHdpZGdldCBpcyBub3QgTm9uZSBhbmQgaGFzYXR0cihzZWxmLl9jdXJyZW50d2lkZ2V0LCAiaWRsZSIpOgorCQkJaWYgc2VsZi5fY3VycmVudHdpZGdldC5fYmluZGluZ3MuaGFzX2tleSgiPGlkbGU+Iik6CisJCQkJY2FsbGJhY2sgPSBzZWxmLl9jdXJyZW50d2lkZ2V0Ll9iaW5kaW5nc1siPGlkbGU+Il0KKwkJCQlpZiBjYWxsYmFjaygpOgorCQkJCQlyZXR1cm4KKwkJCXNlbGYuX2N1cnJlbnR3aWRnZXQuaWRsZSgpCisKKwlkZWYgeHh4X19fc2VsZWN0KHNlbGYsIHdpZGdldCk6CisJCWlmIHNlbGYuX2N1cnJlbnR3aWRnZXQgPT0gd2lkZ2V0OgorCQkJcmV0dXJuCisJCWlmIHNlbGYuX2JpbmRpbmdzLmhhc19rZXkoIjxzZWxlY3Q+Iik6CisJCQljYWxsYmFjayA9IHNlbGYuX2JpbmRpbmdzWyI8c2VsZWN0PiJdCisJCQlpZiBjYWxsYmFjayh3aWRnZXQpOgorCQkJCXJldHVybgorCQlpZiB3aWRnZXQgaXMgTm9uZToKKwkJCWlmIHNlbGYuX2N1cnJlbnR3aWRnZXQgaXMgbm90IE5vbmU6CisJCQkJc2VsZi5fY3VycmVudHdpZGdldC5zZWxlY3QoMCkKKwkJZWxpZiB0eXBlKHdpZGdldCkgPT0gSW5zdGFuY2VUeXBlIGFuZCB3aWRnZXQuX3NlbGVjdGFibGU6CisJCQl3aWRnZXQuc2VsZWN0KDEpCisJCWVsaWYgd2lkZ2V0ID09IC0xIG9yIHdpZGdldCA9PSAxOgorCQkJaWYgbGVuKHNlbGYuX3RhYmNoYWluKSA8PSAxOgorCQkJCXJldHVybgorCQkJdGVtcCA9IHNlbGYuX3RhYmNoYWluWyhzZWxmLl90YWJjaGFpbi5pbmRleChzZWxmLl9jdXJyZW50d2lkZ2V0KSArIHdpZGdldCkgJSBsZW4oc2VsZi5fdGFiY2hhaW4pXQorCQkJdGVtcC5zZWxlY3QoMSkKKwkJZWxzZToKKwkJCXJhaXNlIFR5cGVFcnJvciwgIldpZGdldCBpcyBub3Qgc2VsZWN0YWJsZSIKKwkKKwlkZWYgc2V0ZGVmYXVsdGJ1dHRvbihzZWxmLCBuZXdkZWZhdWx0YnV0dG9uID0gTm9uZSwgKmtleXMpOgorCQlpZiBuZXdkZWZhdWx0YnV0dG9uID09IHNlbGYuX2RlZmF1bHRidXR0b246CisJCQlyZXR1cm4KKwkJaWYgc2VsZi5fZGVmYXVsdGJ1dHRvbjoKKwkJCXNlbGYuX2RlZmF1bHRidXR0b24uX3NldGRlZmF1bHQoMCkKKwkJaWYgbm90IG5ld2RlZmF1bHRidXR0b246CisJCQlzZWxmLmJpbmQoInJldHVybiIsIE5vbmUpCisJCQlzZWxmLmJpbmQoImVudGVyIiwgTm9uZSkKKwkJCXJldHVybgorCQlpbXBvcnQgV2NvbnRyb2xzCisJCWlmIG5vdCBXYmFzZS5IYXNCYXNlQ2xhc3MobmV3ZGVmYXVsdGJ1dHRvbiwgV2NvbnRyb2xzLkJ1dHRvbik6CisJCQlyYWlzZSBUeXBlRXJyb3IsICJ3aWRnZXQgaXMgbm90IGEgYnV0dG9uIgorCQlzZWxmLl9kZWZhdWx0YnV0dG9uID0gbmV3ZGVmYXVsdGJ1dHRvbgorCQlzZWxmLl9kZWZhdWx0YnV0dG9uLl9zZXRkZWZhdWx0KDEpCisJCWlmIG5vdCBrZXlzOgorCQkJc2VsZi5iaW5kKCJyZXR1cm4iLCBzZWxmLl9kZWZhdWx0YnV0dG9uLnB1c2gpCisJCQlzZWxmLmJpbmQoImVudGVyIiwgc2VsZi5fZGVmYXVsdGJ1dHRvbi5wdXNoKQorCQllbHNlOgorCQkJZm9yIGtleSBpbiBrZXlzOgorCQkJCXNlbGYuYmluZChrZXksIHNlbGYuX2RlZmF1bHRidXR0b24ucHVzaCkKKwkKKwlkZWYgbmV4dHdpZGdldChzZWxmKToKKwkJc2VsZi54eHhfX19zZWxlY3QoMSkKKwkKKwlkZWYgcHJldmlvdXN3aWRnZXQoc2VsZik6CisJCXNlbGYueHh4X19fc2VsZWN0KC0xKQorCQorCWRlZiBkcmF3d2lkZ2V0Ym91bmRzKHNlbGYsIG9ub2ZmKToKKwkJc2VsZi5fZHJhd3dpZGdldGJvdW5kcyA9IG9ub2ZmCisJCXNlbGYuU2V0UG9ydCgpCisJCVdpbi5JbnZhbFJlY3Qoc2VsZi5fYm91bmRzKQorCQorCWRlZiBfZHJhd2JvdW5kcyhzZWxmKToKKwkJcGFzcworCisJZGVmIF9tYWtldGFiY2hhaW4oc2VsZik6CisJCSMgWFhYIFRoaXMgaGFzIHRvIGNoYW5nZSwgaXQncyBubyBnb29kIHdoZW4gd2UgYXJlIGFkZGluZyBvciBkZWxldGluZyB3aWRnZXRzLgorCQkjIFhYWCBQZXJoYXBzIHdlIHNob3VsZG4ndCBrZWVwIGEgInRhYmNoYWluIiBhdCBhbGwuCisJCXNlbGYuX2hhc3NlbGZyYW1lcyA9IDAKKwkJc2VsZi5fY29sbGVjdHNlbGVjdGFibGV3aWRnZXRzKHNlbGYuX3dpZGdldHMpCisJCWlmIHNlbGYuX2hhc3NlbGZyYW1lcyBhbmQgbGVuKHNlbGYuX3RhYmNoYWluKSA+IDE6CisJCQlzZWxmLl9oYXNzZWxmcmFtZXMgPSAxCisJCWVsc2U6CisJCQlzZWxmLl9oYXNzZWxmcmFtZXMgPSAwCisJCisJZGVmIF9jb2xsZWN0c2VsZWN0YWJsZXdpZGdldHMoc2VsZiwgd2lkZ2V0cyk6CisJCWZvciB3IGluIHdpZGdldHM6CisJCQlpZiB3Ll9zZWxlY3RhYmxlOgorCQkJCXNlbGYuX3RhYmNoYWluLmFwcGVuZCh3KQorCQkJCWlmIFdiYXNlLkhhc0Jhc2VDbGFzcyh3LCBXbGlzdC5MaXN0KToKKwkJCQkJc2VsZi5faGFzc2VsZnJhbWVzID0gMQorCQkJc2VsZi5fY29sbGVjdHNlbGVjdGFibGV3aWRnZXRzKHcuX3dpZGdldHMpCisJCisJZGVmIF9jYWxjYm91bmRzKHNlbGYpOgorCQlzZWxmLl9wb3NzaXplID0gc2VsZi53aWQuR2V0V2luZG93UG9ydCgpLnBvcnRSZWN0WzI6XQorCQl3LCBoID0gc2VsZi5fcG9zc2l6ZQorCQlzZWxmLl9ib3VuZHMgPSAoMCwgMCwgdywgaCkKKwkJc2VsZi53aWQuR2V0V2luZG93Q29udGVudFJnbihzY3JhdGNoUmVnaW9uKQorCQlsLCB0LCByLCBiID0gR2V0UmduQm91bmRzKHNjcmF0Y2hSZWdpb24pCisJCXNlbGYuX2dsb2JhbGJvdW5kcyA9IGwsIHQsIGwgKyB3LCB0ICsgaAorCQlmb3IgdyBpbiBzZWxmLl93aWRnZXRzOgorCQkJdy5fY2FsY2JvdW5kcygpCisJCisJIyBGcmFtZVdvcmsgb3ZlcnJpZGUgbWV0aG9kcworCWRlZiBkb19pbkRyYWcoc2VsZiwgcGFydGNvZGUsIHdpbmRvdywgZXZlbnQpOgorCQl3aGVyZSA9IGV2ZW50WzNdCisJCXNlbGYud2lkLkdldFdpbmRvd0NvbnRlbnRSZ24oc2NyYXRjaFJlZ2lvbikKKwkJd2FzX2wsIHdhc190LCByLCBiID0gR2V0UmduQm91bmRzKHNjcmF0Y2hSZWdpb24pCisJCXdpbmRvdy5EcmFnV2luZG93KHdoZXJlLCBzZWxmLmRyYWdsaW1pdCkKKwkJc2VsZi53aWQuR2V0V2luZG93Q29udGVudFJnbihzY3JhdGNoUmVnaW9uKQorCQlpc19sLCBpc190LCByLCBiID0gR2V0UmduQm91bmRzKHNjcmF0Y2hSZWdpb24pCisJCXNlbGYuX2dsb2JhbGJvdW5kcyA9IFFkLk9mZnNldFJlY3Qoc2VsZi5fZ2xvYmFsYm91bmRzLCAKKwkJCQkJaXNfbCAtIHdhc19sLCBpc190IC0gd2FzX3QpCisJCisJZGVmIGRvX2NoYXIoc2VsZiwgY2hhciwgZXZlbnQpOgorCQkod2hhdCwgbWVzc2FnZSwgd2hlbiwgd2hlcmUsIG1vZGlmaWVycykgPSBldmVudAorCQlrZXkgPSBjaGFyCisJCWlmIGtleW5hbWVzLmhhc19rZXkoa2V5KToKKwkJCWtleSA9IGtleW5hbWVzW2NoYXJdCisJCWlmIG1vZGlmaWVycyAmIEV2ZW50cy5zaGlmdEtleToKKwkJCWtleSA9ICdzaGlmdCcgKyBrZXkKKwkJaWYgbW9kaWZpZXJzICYgRXZlbnRzLmNtZEtleToKKwkJCWtleSA9ICdjbWQnICsga2V5CisJCWlmIG1vZGlmaWVycyAmIEV2ZW50cy5jb250cm9sS2V5OgorCQkJa2V5ID0gJ2NvbnRyb2wnICsga2V5CisJCWlmIHNlbGYuX2JpbmRpbmdzLmhhc19rZXkoIjxrZXk+Iik6CisJCQljYWxsYmFjayA9IHNlbGYuX2JpbmRpbmdzWyI8a2V5PiJdCisJCQlpZiBXYmFzZS5DYWxsYmFja0NhbGwoY2FsbGJhY2ssIDAsIGNoYXIsIGV2ZW50KToKKwkJCQlyZXR1cm4KKwkJaWYgc2VsZi5fYmluZGluZ3MuaGFzX2tleShrZXkpOgorCQkJY2FsbGJhY2sgPSBzZWxmLl9iaW5kaW5nc1trZXldCisJCQlXYmFzZS5DYWxsYmFja0NhbGwoY2FsbGJhY2ssIDAsIGNoYXIsIGV2ZW50KQorCQllbGlmIHNlbGYuX2N1cnJlbnR3aWRnZXQgaXMgbm90IE5vbmU6CisJCQlpZiBzZWxmLl9jdXJyZW50d2lkZ2V0Ll9iaW5kaW5ncy5oYXNfa2V5KGtleSk6CisJCQkJY2FsbGJhY2sgPSBzZWxmLl9jdXJyZW50d2lkZ2V0Ll9iaW5kaW5nc1trZXldCisJCQkJV2Jhc2UuQ2FsbGJhY2tDYWxsKGNhbGxiYWNrLCAwLCBjaGFyLCBldmVudCkKKwkJCWVsc2U6CisJCQkJaWYgc2VsZi5fY3VycmVudHdpZGdldC5fYmluZGluZ3MuaGFzX2tleSgiPGtleT4iKToKKwkJCQkJY2FsbGJhY2sgPSBzZWxmLl9jdXJyZW50d2lkZ2V0Ll9iaW5kaW5nc1siPGtleT4iXQorCQkJCQlpZiBXYmFzZS5DYWxsYmFja0NhbGwoY2FsbGJhY2ssIDAsIGNoYXIsIGV2ZW50KToKKwkJCQkJCXJldHVybgorCQkJCXNlbGYuX2N1cnJlbnR3aWRnZXQua2V5KGNoYXIsIGV2ZW50KQorCQorCWRlZiBkb19jb250ZW50Y2xpY2soc2VsZiwgcG9pbnQsIG1vZGlmaWVycywgZXZlbnQpOgorCQl3aWRnZXQgPSBzZWxmLmZpbmR3aWRnZXQocG9pbnQpCisJCWlmIHdpZGdldCBpcyBub3QgTm9uZToKKwkJCWlmIHNlbGYuX2JpbmRpbmdzLmhhc19rZXkoIjxjbGljaz4iKToKKwkJCQljYWxsYmFjayA9IHNlbGYuX2JpbmRpbmdzWyI8Y2xpY2s+Il0KKwkJCQlpZiBXYmFzZS5DYWxsYmFja0NhbGwoY2FsbGJhY2ssIDAsIHBvaW50LCBtb2RpZmllcnMpOgorCQkJCQlyZXR1cm4KKwkJCWlmIHdpZGdldC5fYmluZGluZ3MuaGFzX2tleSgiPGNsaWNrPiIpOgorCQkJCWNhbGxiYWNrID0gd2lkZ2V0Ll9iaW5kaW5nc1siPGNsaWNrPiJdCisJCQkJaWYgV2Jhc2UuQ2FsbGJhY2tDYWxsKGNhbGxiYWNrLCAwLCBwb2ludCwgbW9kaWZpZXJzKToKKwkJCQkJcmV0dXJuCisJCQlpZiB3aWRnZXQuX3NlbGVjdGFibGU6CisJCQkJd2lkZ2V0LnNlbGVjdCgxLCAxKQorCQkJd2lkZ2V0LmNsaWNrKHBvaW50LCBtb2RpZmllcnMpCisJCisJZGVmIGRvX3VwZGF0ZShzZWxmLCB3aW5kb3csIGV2ZW50KToKKwkJUWQuRXJhc2VSZ24od2luZG93LkdldFdpbmRvd1BvcnQoKS52aXNSZ24pCisJCXNlbGYuZm9yYWxsKCJkcmF3Iiwgd2luZG93LkdldFdpbmRvd1BvcnQoKS52aXNSZ24pCisJCWlmIHNlbGYuX2RyYXd3aWRnZXRib3VuZHM6CisJCQlzZWxmLmZvcmFsbCgiX2RyYXdib3VuZHMiKQorCQorCWRlZiBkb19hY3RpdmF0ZShzZWxmLCBvbm9mZiwgZXZlbnQpOgorCQlpZiBub3Qgb25vZmY6CisJCQlpZiBzZWxmLl9sYXN0cm9sbG92ZXI6CisJCQkJc2VsZi5fbGFzdHJvbGxvdmVyLnJvbGxvdmVyKCgwLCAwKSwgMCkKKwkJCQlzZWxmLl9sYXN0cm9sbG92ZXIgPSBOb25lCisJCXNlbGYuU2V0UG9ydCgpCisJCXNlbGYuZm9yYWxsKCJhY3RpdmF0ZSIsIG9ub2ZmKQorCQlzZWxmLmRyYXcoKQorCQorCWRlZiBkb19wb3N0cmVzaXplKHNlbGYsIHdpZHRoLCBoZWlnaHQsIHdpbmRvdyk6CisJCVdpbi5JbnZhbFJlY3Qoc2VsZi5nZXRncm93cmVjdCgpKQorCQlzZWxmLl9jYWxjYm91bmRzKCkKKwkKKwkjIHV0aWxpdGllcworCWRlZiB0ZW1wY2xpcHJlY3Qoc2VsZiwgdGVtcGNsaXByZWN0KToKKwkJdGVtcGNsaXAgPSBRZC5OZXdSZ24oKQorCQlRZC5SZWN0UmduKHRlbXBjbGlwLCB0ZW1wY2xpcHJlY3QpCisJCXNlbGYudGVtcGNsaXAodGVtcGNsaXApCisJCisJZGVmIHRlbXBjbGlwKHNlbGYsIHRlbXBjbGlwKToKKwkJaWYgaGFzYXR0cihzZWxmLCAic2F2ZWNsaXAiKToKKwkJCXJhaXNlIFdiYXNlLldpZGdldHNFcnJvciwgImFscmVhZHkgaGF2ZSBzYXZlY2xpcCIKKwkJc2VsZi5zYXZlY2xpcCA9IFFkLk5ld1JnbigpCisJCVFkLkdldENsaXAoc2VsZi5zYXZlY2xpcCkKKwkJUWQuU2VjdFJnbihzZWxmLndpZC5HZXRXaW5kb3dQb3J0KCkudmlzUmduLCB0ZW1wY2xpcCwgdGVtcGNsaXApCisJCVFkLlNldENsaXAodGVtcGNsaXApCisJCisJZGVmIHJlc3RvcmVjbGlwKHNlbGYpOgorCQlRZC5TZXRDbGlwKHNlbGYuc2F2ZWNsaXApCisJCWRlbCBzZWxmLnNhdmVjbGlwCisJCisJZGVmIGdldGdyb3dyZWN0KHNlbGYpOgorCQlsLCB0LCByLCBiID0gc2VsZi53aWQuR2V0V2luZG93UG9ydCgpLnBvcnRSZWN0CisJCXJldHVybiAociAtIDE1LCBiIC0gMTUsIHIsIGIpCisJCisJZGVmIGhhc19rZXkoc2VsZiwga2V5KToKKwkJcmV0dXJuIHNlbGYuX3dpZGdldHNkaWN0Lmhhc19rZXkoa2V5KQorCQorCWRlZiBfX2dldGF0dHJfXyhzZWxmLCBhdHRyKToKKwkJZ2xvYmFsIF9zdWNjZXNzY291bnQsIF9mYWlsY291bnQsIF9tYWdpY2NvdW50CisJCWlmIHNlbGYuX3dpZGdldHNkaWN0Lmhhc19rZXkoYXR0cik6CisJCQlfc3VjY2Vzc2NvdW50ID0gX3N1Y2Nlc3Njb3VudCArIDEKKwkJCXJldHVybiBzZWxmLl93aWRnZXRzZGljdFthdHRyXQorCQlpZiBzZWxmLl9jdXJyZW50d2lkZ2V0IGlzIE5vbmUgb3IgKGF0dHJbOjddIDw+ICdkb21lbnVfJyBhbmQgCisJCQkJYXR0cls6NF0gPD4gJ2Nhbl8nIGFuZCBhdHRyIDw+ICdpbnNlcnQnKToKKwkJCV9mYWlsY291bnQgPSBfZmFpbGNvdW50ICsgMQorCQkJcmFpc2UgQXR0cmlidXRlRXJyb3IsIGF0dHIKKwkJIyBzcGVjaWFsIGNhc2U6IGlmIGEgZG9tZW51X3h4eCwgY2FuX3h4eCBvciBpbnNlcnQgbWV0aG9kIGlzIGFza2VkIGZvciwgCisJCSMgc2VlIGlmIHRoZSBhY3RpdmUgd2lkZ2V0IHN1cHBvcnRzIGl0CisJCV9tYWdpY2NvdW50ID0gX21hZ2ljY291bnQgKyAxCisJCXJldHVybiBnZXRhdHRyKHNlbGYuX2N1cnJlbnR3aWRnZXQsIGF0dHIpCisKK19zdWNjZXNzY291bnQgPSAwCitfZmFpbGNvdW50ID0gMAorX21hZ2ljY291bnQgPSAwCisKK2NsYXNzIERpYWxvZyhXaW5kb3cpOgorCQorCXdpbmRvd2tpbmQgPSBXaW5kb3dzLm1vdmFibGVEQm94UHJvYworCQorCSMgdGhpcyBfX2luaXRfXyBzZWVtcyByZWR1bmRhbnQsIGJ1dCBpdCdzIG5vdDogaXQgaGFzIGxlc3MgYXJncworCWRlZiBfX2luaXRfXyhzZWxmLCBwb3NzaXplLCB0aXRsZSA9ICIiKToKKwkJV2luZG93Ll9faW5pdF9fKHNlbGYsIHBvc3NpemUsIHRpdGxlKQorCQorCWRlZiBjYW5fY2xvc2Uoc2VsZiwgKmFyZ3MpOgorCQlyZXR1cm4gMAorCQorCWRlZiBnZXR3aW5kb3dib3VuZHMoc2VsZiwgc2l6ZSwgbWluc2l6ZSA9IE5vbmUpOgorCQlzY3JlZW5ib3VuZHMgPSBzbCwgc3QsIHNyLCBzYiA9IFFkLnFkLnNjcmVlbkJpdHMuYm91bmRzCisJCXcsIGggPSBzaXplCisJCWwgPSBzbCArIChzciAtIHNsIC0gdykgLyAyCisJCXQgPSBzdCArIChzYiAtIHN0IC0gaCkgLyAzCisJCXJldHVybiBsLCB0LCBsICsgdywgdCArIGgKKwkKK2NsYXNzIE1vZGFsRGlhbG9nKERpYWxvZyk6CisJCisJZGVmIF9faW5pdF9fKHNlbGYsIHBvc3NpemUsIHRpdGxlID0gIiIpOgorCQlEaWFsb2cuX19pbml0X18oc2VsZiwgcG9zc2l6ZSwgdGl0bGUpCisJCWlmIHRpdGxlOgorCQkJc2VsZi53aW5kb3draW5kID0gV2luZG93cy5tb3ZhYmxlREJveFByb2MKKwkJZWxzZToKKwkJCXNlbGYud2luZG93a2luZCA9IFdpbmRvd3MuZEJveFByb2MKKwkKKwlkZWYgb3BlbihzZWxmKToKKwkJaW1wb3J0IFcKKwkJaWYgbm90IFcuX2FwcGxpY2F0aW9uOgorCQkJcmFpc2UgVy5XaWRnZXRzRXJyb3IsICdXIG5vdCBwcm9wZXJseSBpbml0aWFsaXplZDogdW5rbm93biBBcHBsaWNhdGlvbicKKwkJRGlhbG9nLm9wZW4oc2VsZikKKwkJc2VsZi5hcHAgPSBXLl9hcHBsaWNhdGlvbgorCQlzZWxmLmRvbmUgPSAwCisJCU1lbnUuSGlsaXRlTWVudSgwKQorCQlzZWxmLm1haW5sb29wKCkKKwkKKwlkZWYgY2xvc2Uoc2VsZik6CisJCWlmIG5vdCBzZWxmLndpZDoKKwkJCXJldHVybgkjIHdlIGFyZSBhbHJlYWR5IGNsb3NlZAorCQlzZWxmLmRvbmUgPSAxCisJCWRlbCBzZWxmLmFwcAorCQlEaWFsb2cuY2xvc2Uoc2VsZikKKwkKKwlkZWYgbWFpbmxvb3Aoc2VsZik6CisJCXNhdmV5aWVsZCA9IE1hY09TLkVuYWJsZUFwcHN3aXRjaCgtMSkKKwkJd2hpbGUgbm90IHNlbGYuZG9uZToKKwkJCSNzZWxmLmRvMWV2ZW50KCkKKwkJCXNlbGYuZG8xZXZlbnQoCUV2ZW50cy5rZXlEb3duTWFzayArIAorCQkJCQkJRXZlbnRzLmF1dG9LZXlNYXNrICsgCisJCQkJCQlFdmVudHMuYWN0aXZNYXNrICsgCisJCQkJCQlFdmVudHMudXBkYXRlTWFzayArIAorCQkJCQkJRXZlbnRzLm1Eb3duTWFzayArCisJCQkJCQlFdmVudHMubVVwTWFzaywgCisJCQkJCQkxMCkKKwkJTWFjT1MuRW5hYmxlQXBwc3dpdGNoKHNhdmV5aWVsZCkKKwkKKwlkZWYgZG8xZXZlbnQoc2VsZiwgbWFzayA9IEV2ZW50cy5ldmVyeUV2ZW50LCB3YWl0ID0gMCk6CisJCW9rLCBldmVudCA9IHNlbGYuYXBwLmdldGV2ZW50KG1hc2ssIHdhaXQpCisJCWlmIERsZy5Jc0RpYWxvZ0V2ZW50KGV2ZW50KToKKwkJCWlmIHNlbGYuYXBwLmRvX2RpYWxvZ2V2ZW50KGV2ZW50KToKKwkJCQlyZXR1cm4KKwkJaWYgb2s6CisJCQlzZWxmLmRpc3BhdGNoKGV2ZW50KQorCQllbHNlOgorCQkJc2VsZi5hcHAuaWRsZShldmVudCkKKwkKKwlkZWYgZG9fa2V5RG93bihzZWxmLCBldmVudCk6CisJCXNlbGYuZG9fa2V5KGV2ZW50KQorCQorCWRlZiBkb19hdXRvS2V5KHNlbGYsIGV2ZW50KToKKwkJaWYgbm90IGV2ZW50Wy0xXSAmIEV2ZW50cy5jbWRLZXk6CisJCQlzZWxmLmRvX2tleShldmVudCkKKwkKKwlkZWYgZG9fa2V5KHNlbGYsIGV2ZW50KToKKwkJKHdoYXQsIG1lc3NhZ2UsIHdoZW4sIHdoZXJlLCBtb2RpZmllcnMpID0gZXZlbnQKKwkJdyA9IFdpbi5Gcm9udFdpbmRvdygpCisJCWlmIHcgPD4gc2VsZi53aWQ6CisJCQlyZXR1cm4KKwkJYyA9IGNocihtZXNzYWdlICYgRXZlbnRzLmNoYXJDb2RlTWFzaykKKwkJaWYgbW9kaWZpZXJzICYgRXZlbnRzLmNtZEtleToKKwkJCXNlbGYuYXBwLmNoZWNrbWVudXMoc2VsZikKKwkJCXJlc3VsdCA9IE1lbnUuTWVudUtleShvcmQoYykpCisJCQlpZCA9IChyZXN1bHQ+PjE2KSAmIDB4ZmZmZgkjIEhpIHdvcmQKKwkJCWl0ZW0gPSByZXN1bHQgJiAweGZmZmYJCSMgTG8gd29yZAorCQkJaWYgaWQ6CisJCQkJc2VsZi5hcHAuZG9fcmF3bWVudShpZCwgaXRlbSwgTm9uZSwgZXZlbnQpCisJCQkJcmV0dXJuCisJCXNlbGYuZG9fY2hhcihjLCBldmVudCkKKwkKKwlkZWYgZG9fbW91c2VEb3duKHNlbGYsIGV2ZW50KToKKwkJKHdoYXQsIG1lc3NhZ2UsIHdoZW4sIHdoZXJlLCBtb2RpZmllcnMpID0gZXZlbnQKKwkJcGFydGNvZGUsIHdpZCA9IFdpbi5GaW5kV2luZG93KHdoZXJlKQorCQkjCisJCSMgRmluZCB0aGUgY29ycmVjdCBuYW1lLgorCQkjCisJCWlmIEZyYW1lV29yay5wYXJ0bmFtZS5oYXNfa2V5KHBhcnRjb2RlKToKKwkJCW5hbWUgPSAiZG9fIiArIEZyYW1lV29yay5wYXJ0bmFtZVtwYXJ0Y29kZV0KKwkJZWxzZToKKwkJCW5hbWUgPSAiZG9fJWQiICUgcGFydGNvZGUKKwkJCisJCWlmIG5hbWUgPT0gImRvX2luRGVzayI6CisJCQlNYWNPUy5IYW5kbGVFdmVudChldmVudCkKKwkJCXJldHVybgorCQlpZiB3aWQgPT0gc2VsZi53aWQ6CisJCQl0cnk6CisJCQkJaGFuZGxlciA9IGdldGF0dHIoc2VsZiwgbmFtZSkKKwkJCWV4Y2VwdCBBdHRyaWJ1dGVFcnJvcjoKKwkJCQloYW5kbGVyID0gc2VsZi5hcHAuZG9fdW5rbm93bnBhcnRjb2RlCisJCWVsc2U6CisJCQkjTWFjT1MuSGFuZGxlRXZlbnQoZXZlbnQpCisJCQlyZXR1cm4JCQorCQloYW5kbGVyKHBhcnRjb2RlLCB3aWQsIGV2ZW50KQorCQorCWRlZiBkaXNwYXRjaChzZWxmLCBldmVudCk6CisJCSh3aGF0LCBtZXNzYWdlLCB3aGVuLCB3aGVyZSwgbW9kaWZpZXJzKSA9IGV2ZW50CisJCWlmIEZyYW1lV29yay5ldmVudG5hbWUuaGFzX2tleSh3aGF0KToKKwkJCW5hbWUgPSAiZG9fIiArIEZyYW1lV29yay5ldmVudG5hbWVbd2hhdF0KKwkJZWxzZToKKwkJCW5hbWUgPSAiZG9fJWQiICUgd2hhdAorCQl0cnk6CisJCQloYW5kbGVyID0gZ2V0YXR0cihzZWxmLCBuYW1lKQorCQlleGNlcHQgQXR0cmlidXRlRXJyb3I6CisJCQl0cnk6CisJCQkJaGFuZGxlciA9IGdldGF0dHIoc2VsZi5hcHAsIG5hbWUpCisJCQlleGNlcHQgQXR0cmlidXRlRXJyb3I6CisJCQkJaGFuZGxlciA9IHNlbGYuYXBwLmRvX3Vua25vd25ldmVudAorCQloYW5kbGVyKGV2ZW50KQorCQorCitkZWYgRnJvbnRXaW5kb3dJbnNlcnQoc3R1ZmYpOgorCWlmIG5vdCBzdHVmZjoKKwkJcmV0dXJuCisJaWYgdHlwZShzdHVmZikgPD4gU3RyaW5nVHlwZToKKwkJcmFpc2UgVHlwZUVycm9yLCAnc3RyaW5nIGV4cGVjdGVkJworCWltcG9ydCBXCisJYXBwID0gVy5nZXRhcHBsaWNhdGlvbigpCisJd2lkID0gV2luLkZyb250V2luZG93KCkKKwlpZiB3aWQgYW5kIGFwcC5fd2luZG93cy5oYXNfa2V5KHdpZCk6CisJCXdpbmRvdyA9IGFwcC5fd2luZG93c1t3aWRdCisJCWlmIGhhc2F0dHIod2luZG93LCAiaW5zZXJ0Iik6CisJCQl0cnk6CisJCQkJd2luZG93Lmluc2VydChzdHVmZikKKwkJCQlyZXR1cm4KKwkJCWV4Y2VwdDoKKwkJCQlwYXNzCisJaW1wb3J0IEVhc3lEaWFsb2dzCisJaWYgRWFzeURpYWxvZ3MuQXNrWWVzTm9DYW5jZWwoCisJCQkiQ2FuuXQgZmluZCB3aW5kb3cgb3Igd2lkZ2V0IHRvIGluc2VydCB0ZXh0IGludG87IGNvcHkgdG8gY2xpcGJvYXJkIGluc3RlYWQ/IiwgCisJCQkxKSA9PSAxOgorCQlpbXBvcnQgU2NyYXAKKwkJU2NyYXAuWmVyb1NjcmFwKCkKKwkJU2NyYXAuUHV0U2NyYXAoJ1RFWFQnLCBzdHVmZikKKworCisjIG5vdCBxdWl0ZSBiYXNlZCBvbiB0aGUgc2FtZSBmdW5jdGlvbiBpbiBGcmFtZVdvcmsJCitfd2luZG93Y291bnRlciA9IDAKKworZGVmIGdldG5leHR3aW5kb3dwb3MoKToKKwlnbG9iYWwgX3dpbmRvd2NvdW50ZXIKKwlyb3dzID0gOAorCWwgPSA0ICogKHJvd3MgKyAxIC0gKF93aW5kb3djb3VudGVyICUgcm93cykgKyBfd2luZG93Y291bnRlciAvIHJvd3MpCisJdCA9IDQ0ICsgMjAgKiAoX3dpbmRvd2NvdW50ZXIgJSByb3dzKQorCV93aW5kb3djb3VudGVyID0gX3dpbmRvd2NvdW50ZXIgKyAxCisJcmV0dXJuIGwsIHQKKworZGVmIHdpbmRvd2JvdW5kcyhwcmVmZXJyZWRzaXplLCBtaW5zaXplID0gTm9uZSk6CisJIlJldHVybiBzZW5zaWJsZSB3aW5kb3cgYm91bmRzIgorCQorCWdsb2JhbCBfd2luZG93Y291bnRlcgorCWlmIGxlbihwcmVmZXJyZWRzaXplKSA9PSA0OgorCQlib3VuZHMgPSBsLCB0LCByLCBiID0gcHJlZmVycmVkc2l6ZQorCQl1bmlvbiA9IFFkLlVuaW9uUmVjdChib3VuZHMsIFFkLnFkLnNjcmVlbkJpdHMuYm91bmRzKQorCQlpZiB1bmlvbiA9PSBRZC5xZC5zY3JlZW5CaXRzLmJvdW5kczoKKwkJCXJldHVybiBib3VuZHMKKwkJZWxzZToKKwkJCXByZWZlcnJlZHNpemUgPSByIC0gbCwgYiAtIHQKKwlpZiBub3QgbWluc2l6ZToKKwkJbWluc2l6ZSA9IHByZWZlcnJlZHNpemUKKwltaW53aWR0aCwgbWluaGVpZ2h0ID0gbWluc2l6ZQorCXdpZHRoLCBoZWlnaHQgPSBwcmVmZXJyZWRzaXplCisJCisJc2wsIHN0LCBzciwgc2IgPSBzY3JlZW5ib3VuZHMgPSBRZC5JbnNldFJlY3QoUWQucWQuc2NyZWVuQml0cy5ib3VuZHMsIDQsIDQpCisJbCwgdCA9IGdldG5leHR3aW5kb3dwb3MoKQorCWlmIChsICsgd2lkdGgpID4gc3I6CisJCV93aW5kb3djb3VudGVyID0gMAorCQlsLCB0ID0gZ2V0bmV4dHdpbmRvd3BvcygpCisJciA9IGwgKyB3aWR0aAorCWIgPSB0ICsgaGVpZ2h0CisJaWYgKHQgKyBoZWlnaHQpID4gc2I6CisJCWIgPSBzYgorCQlpZiAoYiAtIHQpIDwgbWluaGVpZ2h0OgorCQkJYiA9IHQgKyBtaW5oZWlnaHQKKwlyZXR1cm4gbCwgdCwgciwgYgorCitzY3JhdGNoUmVnaW9uID0gUWQuTmV3UmduKCkKKworIyB1dGlsIC0tIG1vdmUgc29tZXdoZXJlIGNvbnZlbmllbnQ/Pz8KK2RlZiBHZXRSZ25Cb3VuZHModGhlX1Jnbik6CisJKHQsIGwsIGIsIHIpID0gc3RydWN0LnVucGFjaygiaGhoaCIsIHRoZV9SZ24uZGF0YVsyOjEwXSkKKwlyZXR1cm4gKGwsIHQsIHIsIGIpCmRpZmYgLS1naXQgYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvUHl0aG9uSURFLnB5IGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL1B5dGhvbklERS5weQpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi5lMWE5NGE2Ci0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL1B5dGhvbklERS5weQpAQCAtMCwwICsxLDU3IEBACisjIGNvcHlyaWdodCAxOTk3IEp1c3QgdmFuIFJvc3N1bSwgTGV0dGVycm9yLiBqdXN0QGtub3dhcmUubmwKKworIyBrZWVwIHRoaXMgKF9fbWFpbl9fKSBhcyBjbGVhbiBhcyBwb3NzaWJsZSwgc2luY2Ugd2UgYXJlIHVzaW5nIAorIyBpdCBsaWtlIHRoZSAibm9ybWFsIiBpbnRlcnByZXRlci4KKworX192ZXJzaW9uX18gPSAnMC45YjEnCisKK2RlZiBpbml0KCk6CisJaW1wb3J0IHN5cworCWltcG9ydCBNYWNPUworCQorCWlmIHN5cy52ZXJzaW9uWzo1XSA9PSAnMS41YTMnOgorCQlkZWYgTXlFbmFibGVBcHBzd2l0Y2goeWllbGQsIAorCQkJCXRhYmxlID0gey0xOjAsIDA6LTEsIDE6MX0sIAorCQkJCUVuYWJsZUFwcHN3aXRjaCA9IE1hY09TLkVuYWJsZUFwcHN3aXRjaCk6CisJCQlyZXR1cm4gdGFibGVbRW5hYmxlQXBwc3dpdGNoKHRhYmxlW3lpZWxkXSldCisJCU1hY09TLkVuYWJsZUFwcHN3aXRjaCA9IE15RW5hYmxlQXBwc3dpdGNoCisJCisJTWFjT1MuRW5hYmxlQXBwc3dpdGNoKC0xKQorCQorCWltcG9ydCBRZCwgUXVpY2tEcmF3CisJUWQuU2V0Q3Vyc29yKFFkLkdldEN1cnNvcihRdWlja0RyYXcud2F0Y2hDdXJzb3IpLmRhdGEpCisJCisJaW1wb3J0IG9zCisJCisJIyBrbHVkZ2UgdG8ga2VlcCBzdGR3aW4ncyBUZXh0RWRpdC5weSBvdXQgdGhlIGRvb3IuLi4KKwlpbXBvcnQgc3RyaW5nCisJZm9yIGkgaW4gcmFuZ2UobGVuKHN5cy5wYXRoKSk6CisJCXBhdGggPSBzeXMucGF0aFtpXQorCQlpZiBzdHJpbmcuZmluZChwYXRoLCAnc3Rkd2luJykgPiAwOgorCQkJZGVsIHN5cy5wYXRoW2ldCisJCQlicmVhaworCQorCXRyeToKKwkJaW1wb3J0IFNwZWNpYWxLZXlzCSMgaWYgdGhpcyBzdWNjZWVkcywgd2Ugc2hvdWxkIGhhdmUgZXZlcnl0aGluZyB3ZSBuZWVkIGluc2lkZSB0aGUgYXBwbGV0LgorCQlkZWwgU3BlY2lhbEtleXMKKwlleGNlcHQgSW1wb3J0RXJyb3I6CisJCSMgcGVyc29uYWwgaGFjayBmb3IgbWUKKwkJd2hlcmVhcmV3ZSA9IG9zLmdldGN3ZCgpCisJCWltcG9ydCBSZXMsIG1hY2ZzCisJCWlmIG9zLnBhdGguZXhpc3RzKG9zLnBhdGguam9pbih3aGVyZWFyZXdlLCAnSURFTGliJykpOgorCQkJc3lzLnBhdGguYXBwZW5kKG9zLnBhdGguam9pbih3aGVyZWFyZXdlLCAnOklERUxpYicpKQorCQkJc3lzLnBhdGguYXBwZW5kKG9zLnBhdGguam9pbih3aGVyZWFyZXdlLCAnOklERUxpYjpXaWRnZXRzJykpCisJCQlSZXMuRlNwT3BlblJlc0ZpbGUobWFjZnMuRlNTcGVjKG9zLnBhdGguam9pbih3aGVyZWFyZXdlLCAnOklERUxpYjpSZXNvdXJjZXM6V2lkZ2V0cy5yc3JjJykpLCAxKQorCQkJUmVzLkZTcE9wZW5SZXNGaWxlKG1hY2ZzLkZTU3BlYyhvcy5wYXRoLmpvaW4od2hlcmVhcmV3ZSwgJ1B5dGhvbklERS5yc3JjJykpLCAxKQorCQllbHNlOgorCQkJb25lYmFjayA9IG9zLnBhdGguc3BsaXQod2hlcmVhcmV3ZSlbMF0KKwkJCXN5cy5wYXRoLmFwcGVuZChvcy5wYXRoLmpvaW4ob25lYmFjaywgJzpGb2c6V2lkZ2V0cycpKQorCQkJUmVzLkZTcE9wZW5SZXNGaWxlKG1hY2ZzLkZTU3BlYyhvcy5wYXRoLmpvaW4ob25lYmFjaywgJzpGb2c6UmVzb3VyY2VzOldpZGdldHMucnNyYycpKSwgMSkKKwkJCVJlcy5GU3BPcGVuUmVzRmlsZShtYWNmcy5GU1NwZWMob3MucGF0aC5qb2luKHdoZXJlYXJld2UsICdQeXRob25JREUucnNyYycpKSwgMSkKKwkKK2luaXQoKQorZGVsIGluaXQKKworIyNpbXBvcnQgdHJhY2UKKyMjdHJhY2Uuc2V0X3RyYWNlKCkKK2ltcG9ydCBQeXRob25JREVNYWluCmRpZmYgLS1naXQgYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvUHl0aG9uSURFLnJzcmMuaHF4IGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL1B5dGhvbklERS5yc3JjLmhxeApuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi41Y2U1ZTYwCi0tLSAvZGV2L251bGwKKysrIGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL1B5dGhvbklERS5yc3JjLmhxeApAQCAtMCwwICsxLDIyMSBAQAorKFRoaXMgZmlsZSBtdXN0IGJlIGNvbnZlcnRlZCB3aXRoIEJpbkhleCA0LjApCisKKzokUCJqRydLW0VOUCU0NWpiRmgqTSEoKmNGUTA1OGQ5JSEzIzMiYmBOZCJTIU4hMyIhISEhK2NpISEjU3EhISEKKyFqW0hFY0dsSUhVY0doUUhFaEhoaFIwbFlqaVtZbElxRWhybHIhMXJwcmAyZiRQImpHJ0tbRU5QJTQ1amJGaCoKK01FKC1KOCgqUENSLWkrNSFiLE1LTDBoSiEhKCpjRlEwNThkOSUhMyEhISElIiEqITIhSDVLWDYiUCMhIzMiTGAKK04hJCxWcmEwVFFwbEdqVFYxaEdwaltIaFlIbWhZaGhVcWhbSXIiMXJySEVsSHAybSZEKmhJcGpoSXFybSJxRnEKK2NyYChgISNbVnJhMmZRbWxHbFJRcGhHalRSMGxHaytoSGhyTHBockFyIVFMcGhbNnIiQExYbFFMWWhrW3IhSSEKKzIqWlZyJFJWLWxHaGlVcWxZcFRbR2hacVhocihyIWZMWWxIcmVyYDRpVkdyaVZgISErMilTbUojMyJASiJDISEKKzQhW20tITJycSEhISE1ISEhISVKIU4hR1MhQDMhTiE4IiEhUyFOITlTIUAzIVEpJk4hKiEmRCEmTiEqISo1ISEKKyEhJUohTiE4KSEhJSEjISMzJGJKISEhJHIhISRyTiFCISFJazMiSiEjckMhJyEhMm1OIUIhIjJaMyJKISZxVCEKKychIUVqTiFCISJyTDMiSiEpcGohJyEhUmZOIUIhI1tAMyJKISxwKiEnISFjY04hQiEkSSszIkohMW1DISchIXIKK2BOIUIhJTFxMyJKITRsVCEnISIsWU4hQiElcWIzIkohOGtqISchIkFVTiFCISZaUTMiSiFBayohJyEiTVJOIUIKKyEnSEQzIkohRGpDISchIltOTiFCISgxMTMiSiFHaVQhJyEibEtOIUIhKHEjMyJKIUpoaiEnISMoSE4hQiEpWWYKKzMiSiFNaCohJyEjNkVOIUIhKkdVMyJKIVFmQyEnISNJQk4hQiErMEgzIkohVGVUISchI1Y5TiFCIStwNTMiSiEKK1hkaiEnISNoNU4hQiEsWSczIkohW2QqISchJCQyTiFCIS1GazMiSiFiY0MhJyEkMi1OIUIhMC1aMyJKIWViVCEKKychJEUqTiFCITBtTDMiSiFpYWohJyEkUidOIUIhMVhAMyJKIWxhKiEnISRjJE4hQiEyRiszIkohcWBDISchJHIKKyFOIUIhMyxxMyJKIiJbVCEnISUrcE4hQiEzbGIzIkoiJVpqISchJUBrTiFCITRWUTMiSiIoWiohJyElTGhOIUIKKyE1RUQzIkoiK1lDISchJVpkTiFCITYsMTMiSiIwWFQhJyEla2FOIUIhNmwjMyJKIjNWaiEnISYnWk4hQiE4VWYKKzMiSiI2ViohJyEmNVZOIUIhOURVMyJKIkBVQyEnISZIU04hQiFAK0gzIkoiQ1RUISchJlVQTiFCIUBrNTMiSiIKK0ZTaiEnISZmTE4hQiFBVSczIkoiSVMqISchJyNJTiFCIUJDazMiSiJMUkMhJyEnMUZOIUIhQypaMyJKIlBRVCEKKychJ0RDTiFCIUNqTDMiSiJTUGohJyEnUUBOIUIhRFRAMyJKIlZQKiEnISdiNk4hQiFFQyszIkoiWk5DISchJ3EKKzMhKiEhTiEjMyEqISFOISEhRilxMyJKImFNVCEnISgrME4hQiFGaWIzIkoiZExqISchKEArTiFCIUdTUTMiSiIKK2hMKiEnIShMKE4hQiFIQkQzIkoia0tDISchKFolTiFCIUkpMTMiSiJwSlQhJyEoayJOIUIhSWkjMyJKIyFJaiEKKychKSZxTiFCIUpSZjMiSiMkSSohJyEpNGxOIUIhS0FVMyJKIydIQyEnISlHaU4hQiFMKEgzIkojKkdUISchKVQKK2VOIUIhTGg1MyJKIy1GaiEnISllYk4hQiFNUiczIkojMkYqISchKiEhRWohJyEqJlpOIUIhTlFmMyJKIzZFKiEKKychKjRWTiFCIVBAVTMiSiNAREMhJyEqR1NOIUIhUSdIMyJKI0NDVCEnISpUUE4hQiFRZjUzIkojRkJqISchKmUKK0xOIUIhUlEnMyJKI0lCKiEnISsiSU4hQiFTOWszIkojTEFDISchKzBGTiFCIVQmWjMiSiNQQFQhJyErQ0NOIUIKKyFUZUwzIkojUzlqISchK1BATiFCIVVQQDMiSiNWOSohJyErYTZOIUIhVjkrMyJKI1o4QyEnIStwM04hQiFYJXEKKzMiSiNhNlQhJyEsKjBOIUIhWGRiMyJKI2Q1aiEnISw5K04hQiFZTlEzIkojaDUqISchLEsoTiFCIVo4RDMiSiMKK2s0QyEnISxZJU4hQiFbJTEzIkojcDNUISchLGoiTiFCIVtkIzMiSiQhMmohJyEtJXFOIUIhYE1mMyJKJCQyKiEKKychLTNsTiFCIWE2VTMiSiQnMUMhJyEtRmlOIUIhYiRIMyJKJCowVCEnIS1TZU4hQiFiYzUzIkokLS1qISchLWQKK2JOIUIhY00nMyJKJDItKiEnITAhW04hQiFkNWszIkokNSxDISchMC1YTiFCIWUjWjMiSiQ5K1QhJyEwQlROIUIKKyFlYkwzIkokQipqISchME5RTiFCIWZMQDMiSiRFKiohJyEwYE1OIUIhaDUrMyJKJEgpQyEnITBtSk4hQiFpInEKKzMiSiRLKFQhJyExKUdOIUIhaWFiMyJKJE4naiEnITE4RE4hQiFqS1EzIkokUicqISchMUpBTiFCIWs0RDMiSiQKK1UmQyEnITFYOE4hQiFsIjEzIkokWSVUISchMWk0TiFCIWxhIzMiSiRgJGohJyEyJTFOIUIhbUpmMyJKJGMkKiEKKychMjMsTiFCIXAzVTMiSiRmI0MhJyEyRilOIUIhcSFIMyJKJGoiVCEnITJTJk4hQiFxYDUzIkokbSFqISchMmQKKyNOIUIhckonMyJKJHIhKiEsRCEmTiEqISZEISZOISEhISJTJSFKMyNHISEhJ0ozIyIhKmQhISFEIiEpJSFSMyEKKyEiUyUhSjMjRyEhIUxKSiEhMVtta3FgJHExW1ghck1WVCEyaWtxYCEjKDZTa3FgISMoNlNrYEojRyEhIWhLMyEKKyQjVGhycnJsciFpWCEjU1ttcmAxLCNKVSxyMm0iTGBWWyEhJStMcmNyIWlYKyEoVm1yYDVHI0oia20yaHIhQ2QKKythMyNHISEhWUtKISIxWjJxcnJociFHQU1xW3JyaXJWciFILUdtMyEiKEdBa3JgKE1lSVZyIUkkOXFbbSJtJFYKKychKmQhISJIJyEhJDlySXJVcmAjcW0zISFbWkVyIUgtK2FgI0chISFAS2AhIUZbY3JrSW0hQXItISEmck5yYCIKK2JhYCNHISEhQEtgISFbW2Nya0ltIVJJLSEhKVtOcmAjcWFgI0chISFAS2AhIW0yY3JrSW0hZUktISEsbE5yYCQKK2BhYCNHISEhOEtgISFtMmNya0ltIWlyLSEhMEFNcm1GIVIzISEmU0YhISxsbXJxUnIhK2hjISEjR2oybSFbWEYKKyFSMyEhK1NGISEpW21yclJyIVoxcWlyNnIiKCkhKDZTa3BgISFGWzZyIVoxcWVJNnIiKVghKDZTa2JgI0chISEKK21LYCEiI1skcHJyY3IhWyJiI1tpISEzVGJwcm0jaWlbYHJbbSNtKVgrcUohIiNaMmhyYCZrI1tkISFBLGBxMm0KKyNtKVtgckltIlIzVjEhKmQhISNiJyEhImJySXJwcmAoOShJUyEhNlZNbUltImlhaGshISIwcUltIm0kVmshISUKK0dlSShyIUkha2NgI0chISFSS0ohIWVJaHJySW0hMVtKISEkVmByYCNxcUohIVZJUnIhJWhpISEha20ybSJpYFYKKzMhKmQhISNEKCEhImJyMnJxcmAjLHBKISFSSSRyISZybSEhIklxSW0hVklCISEpW2ByYCJrZCEjRyEhIVFLYCEKKyFbW2NyclttITFbQiEhJnJgcmAjWXIhISFSSVJyISgsZiEhIWttMm0hW1khIVIzISEqKUYhITIkbXJybHIhIVYKK2YhISFrbTJtIWlyYCEhMEFqcmAha3BKISEjWnJyZCEjRyEhIUZLYCRscnJscnAzISEjWnJyciEhIWlyUnIhImgKK2UhMXJyZCEjRyEhIVFLYCEhZUljcnJbbSExW0IhISRWYHJgI3FyISEhVklSciElaGYhISFrbTJtIWlwISFSMyEKKyFRSUYhITNTR3FKISIjS2hrISElKyhJUyEhM1NrcUohIiNNVmshISUrMVtTISEzU2txSiEiI01WaiEhIWttISEKKyExW04hISRWaiEhLWshISNHcjJycXJgImJwSiEhSFskciEpW20hISJrcUltIUxyQiEhJnJgcmAxWSEhIWtxMyEKKyIxSlZhISElayNbUyEhNlMrcUohIjFKVmshISVrI1tTISE0ZCtxSiEiKDNWayEhJUcjW1MhITRkK3FKISIoM1YKK2shISVHI1tTIXJhaFAhISUtcUohLChDaGBycnJgVjZTISNUaE1yW20mW01TISNUaE1yW20mW01TISNUaE1yW20KKyZbTVMhI1RoTXJbbSZbTVMhI1NbTXJbbSZbTVMhI1NbTXJbbSZbTmQhI1NbTXJbbSZbTmQhI1NbTXJbbSJlOGgKK2ghISkrSFoycXJgQHE2MyEhSFlBcXJgQHFGSiEhSFlBcXJgLDlMciRwcnJsciFILStxISEiI1skYXJgKGAjW2AKKyEhM1ZNcVttIm0iaGkhISUraXIkciFBVXFyW20maWlYKyElZnFyW20jaWhTK3BgISI2R0FxcmBBTUxgUyE2RWwKK3FyYEFNTGBTITFWbHFyYEFNUjNTITFWbHFyYEFNUjNTITFWbHFyYEFNUjNTITFWbHFyYnJNUjNTITFWbGBycnIKK01SM1MhMVVoYHJyck1WNGQhMVVoYHJycmBWNGQhMVVoYHJycmBWNGQhMVVoYHJycmBWNGhTISEjTHFgISI2SSQKK2tyYCcsbTJWciFDaGBxW20iUkkka3JgJ0dtMlZyIUNoTXFbbSJSSDJrcmAnWWlyVnIhRGhNcVttIVZJTiEhNlYKK01xW20iVkdBa3JgJ3FlSUFyckltIVJJSiEhK2hgcmAiSXFKISE2SVJyIStoaSEhIyxrMm0iaWtoa3JgKGAxW04KKyEhK2hrcmAoTVJJVnIhSDFHcjJycnJgKGBSSVZyIUkjR3FbbSJtKmhrcmAoYFJJVnIhSSMscVttIm0qaGtyYCgKK2BSSVZyIUkjR3FJbSFBcU4hISRSbSEhJWttLCRyISlbbCEhJStlSCxyckltITFbSiEhJWhgcmAjcXFKISFWSVIKK3IhKCxpISEha2hbbSJlM1ZsISEia2tJcWVyYCFra0ohITBbYCEhK2ZacmAhR3IhISFGWihyclttIVJJQiEhK2gKK2ByYCJJciEhITZJUnIhLGxmISEjR2hbbSFIW2AhISJoU3JsQXIhMEFVISEhZnIzISEjVWhyISgsbSEhJDlpSXIKK3FyYCIwcEohIUZbJHIhKmhtISEjR3FJbSFIW0IhISVoSHJgJDlyISEhRlpNclkybSEoSFghISQscCEhIWtWSW0KKyFbW2AhaTJycXJgIWtwSiEhMVskciEyJG0hISNxcUltITFbQiEhImhHcnJgISEraFNybDZyISRWViEhIWByMyEKKyExVWhyISxsbSExJHJyW20hI1tCISEiaGByYCRgciEhIWVJUnIhJFZlITBocnIhISFWSE1yWTJtIUFxWCEhJEUKK3AhISErVkltIUhbYCEhMEFLcnJsciEkVmYhISIwbTJtIVtbYCEhKmhqcmAiSXBKISExWWxyITEybSEhImtrMnEKK2RyYCFra2AhIUhyYCEhMTJjcmAkTXFJbSFpclJyITEyanJgJE1qcm0hZUkyciJOZCEhJFMhISpoY3JgJE1tMm0KKyRpcnJySFtCISFoVnJycTJjcmBDayEhIWshISJicUltIUxyQiEhKCxmcmAkOXFJbSFpcjJyIlVkISEiZCEhJFYKK2NyYCRNcUltImlyJGtyYChNbTFNciFIMmBtSXJybTJWcnJyJGNycm0hcmBWWiEhJEhyISEhQXJJcilbIkkoMyEKKyEjTmg5cnIiYjFKISEjTmg5cnIiYjFKISEjTVVxcnIiYjFKISEjTVVxbEltIkhNVnEhISVrW1tJciFZOWtlSWwKK3IhRWprcFttIkhNVnEhISVrVklFciFTWGshMm0hIU1VLCNbSiEhS2VrMVtpISE2VSxwcm0jbSZxcXJbbSNlQVYKK01xW20ibSJoaSEhJStpclJyIURka3JKISsxUlZycmtkayNKISExUlZmcmBHYltbJHJycEAsZUlJciRFaWsjSiEKKyExUixgcmxpayNKISEjY1RibTJyOTYzUyEhImVibTFsciJwOTAjSiEhKDlyYHBybTNpZGRHISEhR0FyJHJpZGQKK0chISFHNkkkaHJgSCxWSDJycnExWShJJSEhKzJsISEjWXFJbSJbSlZrISEmYihJUyEhQSlHcUohIkZLaGshISIKK2JtMm0iZTZWayEhImJqcm0iaWNWayEhJjBtMlZyIUkha3JKJHAhISErcSEhISNbUyEhNlZgcUltIW0yVnIhMiQKK2pyYCNZcSEhIUxyVnIhSSIwcUohIjFOaGshISVrZUlSciEyJGtyYCRgcTJtIUZbUyEhNGVJciEkciEhJUdGW1MKKyEhNGg5bTJtIUhbUyEhM1VZcUltIlIzVmwhISkrRkpWbCEhJStWSU1yITIkbHJgKGBBcikhISZjbSEhJUdtMlYKK3IhSSEraDMhIUxyLHIhSSFHcSEhIUhaTXIhJFZpISEiYnFbbSExW2Qha0ohITZITXIhKCxpISEha3FbbSFGWm0KKyEhJFZTcmAjLG1KJGUhISUrbTIsciEraGkhISUraXJbciEsbFshISUraXIkciEkVmMhISJDciEhIVtbUnIhJnIKK0YhISUraXIyciEoLGYhISRNa1ttIUhbQiEhLGxtcmAjR3IhJFQhISNZa1ttIVtbQiEhKmhtcmAjcWwzISFIWlYKK3IhSC0rbUokZCEhIkltcm0ibSFWaCEhIWtxcm0hKEhpISEkVmByYCQ5bWAhITgyYCFxMnJEISEjR21ybSEoSUIKKyEhKVtVcmAha3BKISFIW2NyISRWbSExTiEhJnJVcmAiYnBKISExW2NyIShWWSEhIWtrW20hTHIlIXAhISEjWzIKK3IhLGxlITJjciEsbFghISRgbTJtIShJMyEhJixwISEha3FJbSFbWVMhISgsZHJgJGBwMyEhQXFWcnAzISExW2MKK3IhIVZtITFOISEkVlVyYCFrcEohISNbY3IhJFZYITFWciEmcmEhMi0hITEyZHJgImtwMyEhW1tociEpW1ghISMKK3FtMm0hNkkzISEmJHAhISFrcUltIVtZUyEhJWhkcmAkOXAzISExWlZycDMhITFbY3JxYCRUISEhK2tbbSEoSTgKKyFyMm0hMVpgISExMlZyYCFrbTMkYyEhI3FwMm0hSFs4ISEsbHByYCJrbCEhIVJJJHIhKCxkISEiOHIzISEoSVIKK3IhMTJEISEia21ycmUhISJia1ttIShJQiEhJWhtcmAha3IhJFQhISFra1ttITZJQiEhJFZtcmAiSWwzISEjWlYKK3IhKFZhITItISEyJGRyYCMscDMhIWlyaHIhKmhYISEjcW0ybSExWzMhISdWbSEhJGBxSW0hI1lYISFsbHJycTIKK2ZyYCFrcEohIVJIVnIhJWhmISEia3IybSFBcmAhazMhIUZaVnIhKFZmISFDSXJycmBycnEsbDMhJDFbcnJtMiQKK3IhcTJycmtoYSEyMyEhYWhycnEyZnJgI3FwSiEnI1tycm0ycnJlSGAhcnJycm0yMnJyYCRyI1tGISEpUm0hISIKK2txSW0hTHBgISJhZWIxSiEhI01VcXFJbSFWSUYhITRoYGtbbSFlSUYhITNWYHIybSFlSWAha0ohIiNaMlVyYCgKK2AjW0YhImhTayNKISExUlMrbEohJ0hNUyshISFrSFtFciJsaWsjSiEhMVJTa21KJGQhIUdJNjNTISEkVGJtMlIKK3IhJFZoITJwMCI0ZCEhJFRJMVppISJlcDAoMyEhKDlyYHBybShSRGhNcnJyTVY0aGshISJFcWAhIWVJUnIhJFYKKzkhISJrcUltITZJSiEhLGxTcmAia3EhISFWSVZyIShWcCExUyEhKVtTcmAjR20hISEjWm0hISFWayEhJWtlSVIKK3IhKCxVITFkISE0aDlxW20iaWBWaSEhIStqYCEhI1tYISEzVVltSW0ibSVobCEhI0RyISEiI1ska3JgKGAjW0oKKyEhJFZsISEpa1tSLGwhISlrW1IsbCEhIUdwYCEhUklWciEkVmkhISMsazJtITFbSiEhKFZqcmAxLCNKISFySiQKK3IjW0ohITRkK3IhISIjVWhScmAiYmxgISIjS2hsISEqa1tLaGwhISFHcSEhITFbVnIhKVtoISEha3FgISNGWTgKK2tyMyRyISEqYltNVmwhISFHcSEhIihJJGxyYCNxbEohITFbWCEhTmg5MVtYISEiaGkhISUraXIkciEkVm0hISMKK2VyISEhUklSciEmcmghIUJHZUFUMDFSK0dyW20mZUFUMDFSK0dyW20nZUFUMDFSK0dIW0YhITNWYHIybSFIW0YKKyEhM1ZNa1ttIVJJQiEhMTJqcmAsTUxlbSQxUHEsUklCISJUZixBY1RJTHEyUnJgJDlsMyRyTGBqYjFOZWtpcnIKK3JtKmViMU5la1tKVmghISMscjJtImlgVmghIUNrUkEpazZBVjlyW20kUkEpazYzJmtlSWxyIlRlYjFOZWtbSlYKK2ghISJicXJtIShIaSEiUHFZSE1Ta0hWbHFyYERZSE1Ta0hWaWtwYCEhMVskciEsbG0hISJKciEkaXJgIStwSiEKKyFbWlZyISRWZiEhI1lyMm0hMVtCISEqaFVyYCFrcEohIUhbRXJyW20hQXJCISEoVktyYCJrbDMhITZJMnIhKVsKK2YhISFrcjJtIVJJQiEhJFZkcnJJciEsbGYhISErcjJtIVtaYCFtcm0haXI4IWxybSEjW2QhISZscCEhIWtxSW0KKyFpcjghISlbVXJyOCEhKFZtcnI4ISEoLFVyYCFHcEohITZJRXJyW20hMVtCISEkVktyYCFrbDMhIShJMnIhJnIKK2UhMmNyISgsZSEyNnJwcm0hSFs4ISEyJHByYCMsbCEhIWVJNnIhK2hlISEjcW0ybSExW2QhISZscCEhIWtxSW0KKyFbWzghIShWVnJgJDlwMyEhNklociEyJGUhISFra1tyZSEhIWtwW3JxcnI4ISEkVktyYCFrbCEkY3JgIWtwMyQKK21yYCFrcDMhIWlyQXJwcm0hSFs4ISEsbHByYCJrbCEhIVtbNnIhKFZlISEjWW0ybSFGW2QhIScscCEhIUdxSW0KKyFtMjghISpoVXJyOCEhKFZtcmAhK3BKISFIWlZyISRWZiEhIklwW3JxcmAha3BKISE2SChyISVoWSEhIWttcm0KKyFGW0IhISFWbXJgImtwMyRkcnJJciEpW2UhISRgckltIVJIYCEhMTJkcmAjcXAzISFlSSRyISRWcCEhIkxyISEKKyFtMlJyISJoZiEhJDlrW20hMVtCISEsbG1yYCFrcEohIVZIVnIhJWhmISEjLHBbcnFyYCJicEohIUhaKHIhKFYKK1khISJJbXJtIVJJQiEhJFZtcmAjWXBKISExWzZycHJtIVtbQiEhImhtcmAkOWwzISEjWzJyITIkZSExcnJyISEKKyFQSWAhIShWanJgIyxwYCFDMVNYaygzIWtGWjJycmplMCgzIWtGWjJycmplMCgzIWtGU1toISEha3FybSFWSUYKKyEnNGYsNjRkITFQcjlycnFZNjRkITFQcjlycnFZNjRkITFQcSxwYCEiI1skZnJybHIhMEFoISElK2lxKHIhSSEKKytsSiEhZUkyciFJIUdwYCEhW1tjciFJIUdwYCEhVkk2cnBbbSExW0YhISlbbHJgIWtsSiEhSFssciElaGghISIKK2JtMm0hTHJgISEpKGwhISQ5cUltITFbSiEhIVZsISEpK0hNVmwhISkrSE1WbCEhIStwYCEhZUlWciElaGkhISEKKytxSiEiSE1WayEhJms2SVMhISFWaSEhI1lwSXJwcmAia3EhISFMcHJyIStoWyEhImJtSW0hW1tKISEoLGtyYCMKK3FxISEhNkkycnBbbSJpYFZqISEha3FbbSJpYFZgISEha21JbSJtIVZqISElR20yKHIhSC0rciEhIUVyYCEhM1YKK2BxW20ibSJoRyEhIUdxYCEiKEVsaXJgImJxYCEiKDNWRyEhImtwSXJwcmAiSXEhISFGWXJyIShWaSEybStxYCEKKyFIWyRyISlbaSEhIWtxW20hUklKISEkVmNyckVyISxsaSEhJUdtMltyISxsaCEhIUdxYCEiNkkkYXJgKDkjW04KKyEhM1ZNbUltIm0iaG0hISJjciEhIVJJUnIhJnJGISFGK1ZBU2sxUHEsbTJFciJZOWs2NlRJTGgsRSEhJDlwW3IKK3FyYCNZcEohIVtaKHIhMEFmISFER0xlbWs2QVZNbTJtImlgVmghISJrcjJtImlgVmghISJrcDJyaHJgKGAjW0YKKyEhKCxtcmAoYChJRiEiUHFHRk1Ta0hWbFtyYCFrcGAhITFbJHIhMEFtISEiM3IhJGlycFMhIStoVXJgIWtmYCEKKyFIW0VyclttITZJQiEhKCxLcmAia3BKISExWlZyISlbZiEhIWtyMm0hTHJCISEkVmRycklyIStoZiEhIStyMm0KKyFbWzgha1ttIWVJOCEhMiRgcmAhR3IzISE4MmQhISRWanJgJDlmSiEhSFpWcmZKISExW0VyclttIShJQiEhJFYKK0tyYCFrcEohISNaVnIhJWhlITJjciEmcmUhMjZycHJtIUhbOCEhMTJwcmAia3AzISFlSFtyISpoZSEhI3FtMm0KKyE2SWQhISYkcCEhIWtxSW0hW1lTISEkVlZyYCQ5ZkohITFbRXJyW3JkITEociEiaGUhMVZyISRWZSEhJE1ySW0KKyExWzghISxsZXJySXIhJWhlISEjcXJJbSFIWzghISxsVnJgImtwMyEhSFskciEoVnAhISIzcjMhITFbUnIhMTIKK0QhISJra1tyRCEhIjBwW3JxcmAha3BKISExWihyISRWZiEhIUdrW20hQXI4IXIybSFGWzghcDJyaHJgImtwMyEKKyFpcmhyISlbZSEhJDlrcm0hVkk4ISEsbGByYCFrcjMhIThbYCFxMm0hI1lYISEraFVyYCFrZmAhIUhbRXJyW20KKyFBckIhIShWS3JgImtwSiEhNkhWciEpW2YhISFrcjJtIVJJQiEhJFZkcnJJciEsbGYhISFHcjJtIVtbQiEhIVYKK1VyYCRNcDMkW3JgIStyMyEhQ1tgISEoVmpyYCJraCEhIjFbJFVyYCNZaCEhIiNaMmZycmxyITBBaCEhJStpciQKK3IiVmpJMUoha0FsbGpyYChNI1tGISEsbFVyYChgI1tGISEraG1yYChgKElGISEqaGRyckVyISRWaCEhImtxcm0KKyExW0YhIShWVHJgIjBwYCEhRlskciEraG0hISJOcWAhIWVJUnIhJFZHISEkOWsybSE2R2QhIStoZXJyaHIhKFYKK2khISMsbTJtIUhbUyEhQSxgcVttIVJJSiEhKCxTcmAjcXEhISE2SVZyISxsaSEhIjBtcnJmcmAoOSNbTiEhJFYKK2tyYChNI1tOISEkVlNyYChgI1tOISE0aGBtSW0ibSFWbSEhIydyISEiI1oya3JgKGAoSUohISJobCEhKUdWQSwKK2whISlHVkEsbCEhJUdbWklyIUkia3FgISMjVWVrcWAhIyNVZWtxYCRyI1tKISEpW2VycmhyISgsaSEhImttSW0KKyFIW0ohISgsa3JgIyxxISEhRlpNciEraGkhISIwcVttIVZJSiEhJFZjcnJFciEsbGkhISFrcVttIWVJSiEhNGgKK2BrSW0iaWBWaiEhJSttMihyIUkhK3IhISFOW2AhISlbanJgImJwYCFDMVZqazFNVElMciRycmxqazFNVElMciQKK3JybGprMU1USUxyJE5yYU05SE1Ta0FpW2BycnI5SE1TazZBVmBycnJNSE5kazZBVUdwYCEiI1oyZnJybHIhLGwKK2YhISQ5bXJtIWVJQiEhLGxtcmAkTXBKISFbWlZyIUkhK3BgISFSSWNyIUkhK3BgISFMcjZycFttIShJRiEhKFYKK2xyYCFrcGAhIUZaUnIhJFZoISEiMG0ybSFbW2AhISZjbSEhJGBxSW0hI1tCISEsa2RyYCIwcEohIUhbRXJyW20KKyFBckIhIShWY3JgImtwSiEhQXJjciEoVmYhISJJa1ttIVJJQiEhJFZtcmAjWXBKISExWzZycHJtIVtbQiEhImgKK21yYCNxcEohISNaVnIhMTJlITFyciEhVnAhISJGcjMhIShJUnIhMTJlISEjLFkybSEoSUIhISVoZnJybHIhJFYKK2YhISFrbXJtITFbQiEhJFZtcmAiMHBKISExWlZyISgsZiEhIStyMm0hSFs4IXAycmhyYCMscDMhIW0yaHIhKVsKK2UhISRNa3JtIVZJOCEhLGxgcmAha3IzISE5MmQhISRWanJgI3FwMyEhSFY2cnAzISExW0VycltyZSEhIUdtcm0KKyEoSTghcjJtITFbOCFrW20hMVs4IXIybSExWzghITEyZXJySXIhKFZlISEjcXJJbSFIWzghISxsVnJgImtwMyEKKyFSSSRyIShWcCEhIkZyMyEhKElSciExMmUhISMsWTJtIShJQiEhJnJmcnJsciEkVmYhISFrbXJtITFbQiEhJFYKK21yYCIwcEohITFaVnIhKCxmISEhK3IybSFIWzghcDJyaHJgIyxwMyEhbTJociEqaGUhISRNa3JtIVtbOCEhLGwKK2ByYCFrcjMhIUEyYCEhMiRqcmAhK3BKISFbVjZyISVoZiEhImtwW3JxcmAiSXBKISFIWzJyIShWZiEhImJyMm0KKyFIW0IhISZyVXJgI0dwSiEhMVtjciEraGYhISFrcDJyaHJgI3FwSiEhKEljciEwQWYhISEra1ttIW0yOCFscm0KKyEjW2QhISpSbSEhIyxxSW0hSFtGISEkVixyYUxZQWNTITFSLE1ycnFZQWNTITFSLE1ycnFxQWNTITFSKyxwYCEKKyIjWjJmcnJsciEsbGYhIXFHRk1TITFSLDlycnI5Rk1TITFSKyxwSiEhW1tjciFILStwYCEhW1pWciFJIStwYCEKKyFWSWNyIUkhK3BgJHJISlhrI01USVZJcnJtKFNrI01TLEFqaHJyciJrMUpTRzZDZGtwYCEhSFtbciEkVmghISIKK2JrSW0hMVtGISElaGByYCNZciEhIUsyYCEhM1ZNcUltIShJSiEhMEEwcmAoYDZJWCEhSlUsRltYISFKVSxGW1gKKyEhIVZoISEjLHBJcnByYCJicSEhIShJUyFyaFZrISEhR3EhISFGW1ZyISlbaSEhImJrMm0hVklKISElaGtyYCMKK1lxISRyI1tYISFOZkcjW2QhcmAhIzFUZCtxYCEhI1tKISEkVmtyYCQ5cSEhIihJJFRyYChNI1tOISEzVmBtSW0KKyJtIVZtISEiUnIhISIjWjJqcmAha3EhISFlRmhyISVoSCEhImtwMnJwcmAoYEZbUyEhIVZbISEhR3FKISJGWyQKK2tyYCMscSEhIUZaTXIhK2hpISEiMHFJbSJMYFZsISEhR21KJGQhISErcWAhIjFaMmtyYCQ5cSEhIihJJFRyYCgKK00jW04hITNWYG1JbSJtIVZtISEiYHIhISFMclJyISgsaCEhIWtjW20hTHE4ISJgVSxBY1MhMVIsOW1ycmxyYEQKK3FBY1MhMVBxLGwzISdSOW1rISRUSVtbUnIhSC0rcGAhIVtaVnIhSSErcGAhIVZJUnIicTBiMUohRzZCWEdtSiQKK2QhIUNiSE1TKyg4ZkdxMm0hMVtGISEoLFRyYCFrcGAhITZJJHIhK2htISEiK3IhJGlyYCErcEohIVtYcnIhJFYKK04hISJrbElyZXJgIklsMyEhQXIyciEoVmYhISIwa1ttIUxyQiEhJFZjcmAjR20zJGQhISFHbXJtIVtbOCFrW20KKyFpcjghITIkYHJgIUdyMyEhNVtkISEkVmpyYCRNcDMhIUxtcnJpYCEhNkhocnBJbSExWmQhISRWY3JgIWtwSiEKKyEoSFZyISZyZSEyMnIhKCxhITItISEyJGRyYCMscDMhIWVIW3IhK2hlISEjcW0ybSE2SWQhISVNcCEhIWtxSW0KKyFbWzghISgsM3JgJDlpYCEhMVpocnBJclYhMjJyISJoZSExVnIhJFZlISEkTXAybSExWyUhbWAhIVtbNnIhKFYKK2UhISNxa3JtIUhbOCEhKFZgcmAia3IzISE1W2QhISRWanJgJDlwMyEhSFhycmlgISE2SGhycEltITFaZCEhJFYKK2NyYCFrcEohISNaVnIhJnJlITIyciEoLGEhMi0hITEyZHJgImtwMyEhZUhbciEqaGUhISNxbTJtIUZbZCEhJVYKK3AhISErcTJyZSEhI3Fjcm0hMVozISEoVllyckFyISZyWSEhIkltcm0hSFtCISElaFVyYCMscEohITFbMnIhKmgKK2EhMjMhISFWY3JgI3FwMyRVcmAkOXAzISFtMiRyISJocCEhIjZyISEhUklSciEoLGghISVHbS1yciEpW1AhISUKKytpcWhycEltIVtaZCEhLGxjcmAkOXBKISFWSFZyIUgtK3BgISFMcjJyIUkhK21KJGQhISJibXJtIm0iaGghISIKK2JrSW0hMVtGISEkVmByYCNxciEhITlJYCEhM1ZgcVttIm0iaGkhISNxY0ltITFaQiEhKVtYcnI2ciEoLFshISIKK2JtSW0hSFtKISElaFNyYCMscSEhITFbKHIhK2hiITI4ISE2VmBtW20hZUlKISE0aGBrSW0iaWBWaiEhJSttMigKK3IhSSFrciEhIUxyWCEhMEFqcmAoOTFbWCEhM1VZbHJtIW0yW3IhWyJiW1tbciFbImJbW1tyITIkaXJgKGA2SVMKKyEhQVQwcUohIkhOaGshISJra3JyZHJgKGBGW1MhcmgsayEhJmJtMiRyIShWayEhJjBtMUlyIUFTK3FgISI2SSQKK2ByYCcsI1tYISFNVSwjW2QhcmAhIzFTWCtxYCEiMVoyYHJgJ1kjW1ghITZWOWpybSJbS2hsISElR2VJJHIhSC0KKytyISEhVTJgISEoVmZyYEQsNjRkITFSLGBsW21DZTlxWWlycXFMYWQhISZxWWlycXFMYWQhISZxWWlycXFMaCwKK2ZyYUxZNjRkITFQcjlycnFZNjRkITFQcjlycnFZNjRkITFQcjlrW3JicmBxcUFjUyExUHFxcnJxcUFjUyExUHEKK3FsSW0nZTltayEiZTBWSDZyIlowYjFKIUc2Q2hZcmBoTUZNUyEoOGZHcnJyTUZNUyEoM1QwUklycmloKWshIVQKKzBMcWhyIlsiYjFKISsxU1tOcmBJYExjUysjTVUsbTFsciEpW20hISE4ciEhIW0wW3IhJFZVISEjcWFbcSJyaywKK3JyISEhJltkISEiaERyYCJia0ohIW0tRXJKSXFMcmAha3IzISEmW2QhISRWRHJgIyxrYCEhI1hBckpJcUxyYCIKK2JyMyEhJjJkISEkVkRyYCJra0okJnJpKHJTW20hNklkISEiNm0hMFZyISZyVSEhJE1hW3EicmssciEkVnAhISEKK0FyISEhUkdjciFJIStrSiEhSFhFckpJcU1yYCNxciEhIScyYCEhNGhgaEltIUFxTiEhM1Y5YXJxInJrMnIhJFYKK20hISFxcWAhIiNZQWxyYCRgakltITFaSiEhM1VZcVttIW0wNnIhMiRxcnJociFCWllxW20hbS0sciEyJGtyYCQKK2BlcnIocmAkYHFybSFtMUVyIUgtK3IhISE2SVMhImBUYlZJJHJbU1pHakltIWVIQiEiUHFHaXJyOVJBVjZyYDIKK2BBa2hNJElyOVY2UyEhJWZZaXJyTVZBLGBgSW0oRlRoOXJxMVlGWjJBcm1JcnJpWCZbW3JgW1JVcWpJbSFSSWAKKyEhI2NjISEkYGoybSExWiUhISxsNXJgKmshISRlISEjLGAybSFWSWAhISgsQHJtRXJyISEhKEgyciEhVnAhISEKK1hwISEhKEgyciEoVkshMChyIVVkISEyOCEhLGwhcmAkYHIhISFSR0VyYVttITFbZCEhJWhNcmAha3IzISErWzMKKyEhJFZNcmAjWWlKISExWShyIVk4ISEyOCFbW3JtISEjcWVbcidyYCIwcjMhIUhaMnIhKFZwISEhVXAhISExWjIKK3IhKFZLITAociFWaSEhMjghITExcnJyYCEhK2hAcm1FciEkVnAhISJJaXJtITZJZCEhI1ZjITEyciElaEshISQKKzlkW20jSEohIXAzISFWRiRyISxsbSEhImtlW3IncnJgISEkVk1yYCFHcjMhISxyLSEhKmhQcmAoYCNaJSEhKFYKKzVyYClrISEkZSEhIjBgMm0hRltgISEiaEBybUlyISxsbCEhJDlqSW0hZUlgISEkJGMhISUrbTFFciElaEkhISQKKzllMm0hTHJpIXAhISFWRixyITBBayEhImtlcnIpcmAoYChJWCEhJFZQcmAha3IhISFYMikhITZWTXFbbSJMcTIKK2tyYCcsaXJWciEoVkghISVrZUlWciFDaDlxW20iVkdBa3JgJ1llSVZyIURmcXFbbSJWM1ZxITIzISEzVXFxW3IKK3JbW1ZyIUVrWXFbbSJbVWhrcmAncVZJVnIhRWtZcVttImVEaGtyYCg5MVtOISEpW2tyYCg5UklWciFHQEdxW20KKyJpamhrcmAoTUxyY3Jycm0iaWlba3JgKE1MclZyIUgxLHFbbSJtKVtrcmAoYExyVnIhWyMsbTJbciFJIjBxMyEKKyJBciRscmAsYExyJGxyYCxgUkkkbHJgKGBBclghITQsYSEiTitMcEFycnIjWTFKIStMcEFycnIjWTFKIStMcEEKK3JyciNxMVlYISFBVjlyW20mW01TISEoVjlyW20mW05kISEoVjlyW20mW05kISEoVjlyW20mW05kISEoK3FyW20KKyJbTmhtITIpISFBK3FyW20mW1IpISEoK3FyW20mW1IpISElZnFyW20mW1IpISElZnFyW20mZUEpISElZnFyW20KKyZlQVMhISVmcXJbbSZlQVMhISVmcXJbbSJlQVZmISNKa1tbJHJycDlrISEha1tbJHJycEAsISEha1tbJHJycEAKKywjSiFrW1skcnJwQCwjSiFrW1skcnJjTTlMYFMhMVVoYHJyck1MYFMhMVVoYHJyck1MYFMhMVVoYHJyck1SM1MKKyExVWhgcnJyTVIzUyExVWhgcnJyTVIzUyEoRGhNcnJyTVIzVmghIk5HVkgycnJxMVkoMyFHVkgycnJxMVkoMyEKK0dWSDJycnExWShJUyEhKGhZISEhR3EzISEoSU4hISJoOSEhIWtxMyEhMVtOISEkVmohISFHcTMhIShJTiFsYCEKKyEoSU4hISJoaiEhIWtxMyEhMVtOISEkVmohISFrcTMhITFbISEhImhqISEhR3EzISEoSU4hISJoaiEhJUcjW1MKKyEhNGQrcUohIigzVmshISVHI1tTISE0ZCtxSiRyI1tTIXJgVmEhMm0rcUokciNbUyFyYFZoISEhJ0ozIyIhKmQKKyEhIUQiISklIVIzISEiUyUhSjMjRyEhISdKMyMiISpkISEhJHIhISEhJyEiQSEoQiJKYCknISElIiEqISghRzMKKyEhJCErISEhISVKIzMiYEIhJjMiWiFBUiEhSihjISEhIUhgISghNlMxKiNLIjgmIi01ODAiOSVQMjZMTjAqI0sKKzNAOTQpNmRpVDFOYVRCSyVOKyYiQzklSzI2TE5rOCdhZUNkUFpGYSVOKyYiQzklSzI2TE5rNkAmTTFOYVRCS04KK04rJiJDOSVLMjZMTms2QCZNMU5hVEJNVGRFZnBYQlFwaSdiM1M4JlA4NSVwMSs2VDBCQC1rNidQTDFSME1GUVAKK2BHJ1BaQ2AhISEiIjg0OUs4Ryg0aUchI1MtJCVpLTMjMyIzVDNpISFmViEhISJrJUohISEhI1AkSiEqYG0hISEKK3FJISMzIiFUM2khI0YyISEhImslSiEhISEwISM0QiEhISEhOGAsTVBMLTVGYCxNUEwtNSNULTZOajBiIitHQTAKK2QpKENLRUwiNUVoMGNHQGRKKyVhUEcoNFBGUipbRkxOISEhIUchKiZKISEhISM4YVBHKDRQRlIqW0ZKYUxINSIKKy1DQTRkQ0EqYkVoKSEhISUhISEhVjJKISErTWkhISEkUSFiLVJxI1EhISEhISghJDEhIUMzNTgwOCEhISExTjQKKy02ZEYhISEiJzQlUDg2ISEhISYqNjkmKU0hISEhQU5HOVlkTiEhISJVOGRQRDQzISMhKENmQ0EqYyEhJSFRSigKK2MhIWAhTiFKImUhISchISFTcEojMyIhKDghKiElKzQpIU4hQCJycm0hISNOUyFiLVJYI0oicnJtISEjUVIhKiEKKyVyaiElISEhVFpgLU0qUjMhIUlyciEhIVRiMy1NKmszISEycnIhISFUZWAtTStBISEhSXJyISEhVGozLU0qa0oKKyEhW3JyISEhVSgzLU0qZUomM0AqW0dBMyYzQCpbR0EzLEYoUGREJ3BaKSdhW0NmcSI0MzoKZGlmZiAtLWdpdCAiYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy8gIEhvbGQgb3B0aW9uIHRvIG9wZW4gYSBzY3JpcHRcMzAyXDIxMiIgImIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL1NjcmlwdHMvICBIb2xkIG9wdGlvbiB0byBvcGVuIGEgc2NyaXB0XDMwMlwyMTIiCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjA2MmM2NGMKLS0tIC9kZXYvbnVsbAorKysgImIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL1NjcmlwdHMvICBIb2xkIG9wdGlvbiB0byBvcGVuIGEgc2NyaXB0XDMwMlwyMTIiCkBAIC0wLDAgKzEsNCBAQAorIkhvbGQgdGhlIG9wdGlvbiBrZXkgdG8gb3BlbiBhIHNjcmlwdCBpbnN0ZWFkIG9mIHJ1bm5pbmcgaXQuIgorCitpbXBvcnQgVworVy5NZXNzYWdlKF9fZG9jX18pCmRpZmYgLS1naXQgYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy8gIHNlcGFyYXRvciAtLS0gYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy8gIHNlcGFyYXRvciAtLS0KbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYTI0ZGNkNwotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy9TY3JpcHRzLyAgc2VwYXJhdG9yIC0tLQpAQCAtMCwwICsxIEBACitBIHNlcGFyYXRvciBlbmRzIHdpdGggJy0tLScKZGlmZiAtLWdpdCAiYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy9IYWNrL1JlbW92ZSAucHljIGZpbGVzXDMwMlwyMTIiICJiL01hYy9Db250cmliL1B5SURFLXNyYy9TY3JpcHRzL0hhY2svUmVtb3ZlIC5weWMgZmlsZXNcMzAyXDIxMiIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uODBmNTJkNQotLS0gL2Rldi9udWxsCisrKyAiYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy9IYWNrL1JlbW92ZSAucHljIGZpbGVzXDMwMlwyMTIiCkBAIC0wLDAgKzEsMjAgQEAKK2ltcG9ydCBzeXMKK2ltcG9ydCBvcworaW1wb3J0IG1hY2ZzCisKK2RlZiB3YWxrKHRvcCk6CisJbmFtZXMgPSBvcy5saXN0ZGlyKHRvcCkKKwlmb3IgbmFtZSBpbiBuYW1lczoKKwkJcGF0aCA9IG9zLnBhdGguam9pbih0b3AsIG5hbWUpCisJCWlmIG9zLnBhdGguaXNkaXIocGF0aCk6CisJCQl3YWxrKHBhdGgpCisJCWVsc2U6CisJCQlpZiBwYXRoWy00Ol0gPT0gJy5weWMnIGFuZCBvcy5wYXRoLmV4aXN0cyhwYXRoWzotMV0pOgorCQkJCXByaW50ICJkZWxldGluZzoiLCBwYXRoCisJCQkJb3MucmVtb3ZlKHBhdGgpCisJCQllbGlmIHBhdGhbLTQ6XSA9PSAnLnB5Yyc6CisJCQkJcHJpbnQgIiEhISAtLS0tLS0gLnB5YyBmaWxlIHdpdGhvdXQgLnB5IGZpbGU6IiwgcGF0aAorCitmc3MsIG9rID0gbWFjZnMuR2V0RGlyZWN0b3J5KCdTZWxlY3QgdGhlIHN0YXJ0aW5nIGZvbGRlcjonKQoraWYgb2s6CisJd2Fsayhmc3MuYXNfcGF0aG5hbWUoKSkKZGlmZiAtLWdpdCAiYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy9IYWNrL1Rvb2xib3ggQXNzaXN0YW50XDMwMlwyMTIiICJiL01hYy9Db250cmliL1B5SURFLXNyYy9TY3JpcHRzL0hhY2svVG9vbGJveCBBc3Npc3RhbnRcMzAyXDIxMiIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uZTU1YzAwYQotLS0gL2Rldi9udWxsCisrKyAiYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy9IYWNrL1Rvb2xib3ggQXNzaXN0YW50XDMwMlwyMTIiCkBAIC0wLDAgKzEsNTMgQEAKK2ltcG9ydCBhZXRvb2xzCitpbXBvcnQgU3RhbmRhcmRfU3VpdGUKK2ltcG9ydCBSZXF1aXJlZF9TdWl0ZQoraW1wb3J0IE1hY09TCitpbXBvcnQgVworCisKK2NsYXNzIFRvb2xib3goYWV0b29scy5UYWxrVG8sIFN0YW5kYXJkX1N1aXRlLlN0YW5kYXJkX1N1aXRlKToKKwkKKwlkZWYgTG9va3VwVG9waWMoc2VsZiwgX29iamVjdCwgX2F0dHJpYnV0ZXM9e30sICoqX2FyZ3VtZW50cyk6CisJCV9jb2RlID0gJ0RhblInCisJCV9zdWJjb2RlID0gJ1JFRiAnCisKKwkJI2FldG9vbHMua2V5c3Vic3QoX2FyZ3VtZW50cywgc2VsZi5fYXJnbWFwX09wZW5VUkwpCisJCV9hcmd1bWVudHNbJy0tLS0nXSA9IF9vYmplY3QKKworCisJCV9yZXBseSwgX2FyZ3VtZW50cywgX2F0dHJpYnV0ZXMgPSBzZWxmLnNlbmQoX2NvZGUsIF9zdWJjb2RlLAorCQkJCV9hcmd1bWVudHMsIF9hdHRyaWJ1dGVzKQorCQlpZiBfYXJndW1lbnRzLmhhc19rZXkoJ2Vycm4nKToKKwkJCXJhaXNlIE1hY09TLkVycm9yLCBhZXRvb2xzLmRlY29kZWVycm9yKF9hcmd1bWVudHMpCisJCSMgWFhYWCBPcHRpb25hbGx5IGRlY29kZSByZXN1bHQKKwkJaWYgX2FyZ3VtZW50cy5oYXNfa2V5KCctLS0tJyk6CisJCQlyZXR1cm4gX2FyZ3VtZW50c1snLS0tLSddCisJCisKK2NsYXNzIFRvb2xib3hBc3NpOgorCQorCWRlZiBfX2luaXRfXyhzZWxmKToKKwkJc2VsZi50YWxrZXIgPSBUb29sYm94KCdBTFRWJykKKwkJc2VsZi53ID0gVy5XaW5kb3coKDIwMCwgMTAwKSwgIlRvb2xib3ggQXNzaXN0YW50IikKKwkJc2VsZi53LmJ1dHRvbiA9IFcuQnV0dG9uKCgtOTQsIC0zMiwgODAsIDE2KSwgIkxvb2t1cCIsIHNlbGYubG9va3VwKQorCQlzZWxmLncucHJvbXB0ID0gVy5UZXh0Qm94KCgxMCwgOCwgLTEwLCAxNSksICJFbnRlciB0b3BpYzoiKQorCQlzZWxmLncuZWRpdCA9IFcuRWRpdFRleHQoKDEwLCAyNCwgLTEwLCAyMCkpCisJCXNlbGYudy5zZXRkZWZhdWx0YnV0dG9uKHNlbGYudy5idXR0b24pCisJCXNlbGYudy5vcGVuKCkKKwkKKwlkZWYgbG9va3VwKHNlbGYpOgorCQlsb29rdXAgPSBzZWxmLncuZWRpdC5nZXQoKQorCQl0cnk6CisJCQlzZWxmLnRhbGtlci5Mb29rdXBUb3BpYyhsb29rdXApCisJCWV4Y2VwdCBNYWNPUy5FcnJvciwgZGV0YWlsOgorCQkJaWYgdHlwZShkZXRhaWwpID09IHR5cGUoKCkpOgorCQkJCWlmIGRldGFpbFswXSA9PSAtNjA5OgorCQkJCQlzZWxmLnRhbGtlci5zdGFydCgpCisJCQkJCXRyeToKKwkJCQkJCXNlbGYudGFsa2VyLkxvb2t1cFRvcGljKGxvb2t1cCkKKwkJCQkJCXJldHVybgorCQkJCQlleGNlcHQgTWFjT1MuRXJyb3I6CisJCQkJCQlwYXNzCisJCQlXLk1lc3NhZ2UoIlJlcXVlc3RlZCB0b3BpYyBub3QgZm91bmQuIikKKworVG9vbGJveEFzc2koKQpkaWZmIC0tZ2l0IGEvTWFjL0NvbnRyaWIvUHlJREUtc3JjL1NjcmlwdHMvSW5zZXJ0IGIvTWFjL0NvbnRyaWIvUHlJREUtc3JjL1NjcmlwdHMvSW5zZXJ0Cm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLmU2OWRlMjkKLS0tIC9kZXYvbnVsbAorKysgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy9JbnNlcnQKZGlmZiAtLWdpdCAiYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy9JbnNlcnQgZmlsZSBuYW1lXDMwMlwyMTIiICJiL01hYy9Db250cmliL1B5SURFLXNyYy9TY3JpcHRzL0luc2VydCBmaWxlIG5hbWVcMzAyXDIxMiIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uNzYzMmY4ZQotLS0gL2Rldi9udWxsCisrKyAiYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy9JbnNlcnQgZmlsZSBuYW1lXDMwMlwyMTIiCkBAIC0wLDAgKzEsNiBAQAoraW1wb3J0IG1hY2ZzCisKK2Zzcywgb2sgPSBtYWNmcy5TdGFuZGFyZEdldEZpbGUoKQoraWYgb2s6CisJaW1wb3J0IFcKKwlXLkZyb250V2luZG93SW5zZXJ0KCciJXMiJyAlIGZzcy5hc19wYXRobmFtZSgpKQpkaWZmIC0tZ2l0ICJhL01hYy9Db250cmliL1B5SURFLXNyYy9TY3JpcHRzL0luc2VydCBmb2xkZXIgbmFtZVwzMDJcMjEyIiAiYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy9JbnNlcnQgZm9sZGVyIG5hbWVcMzAyXDIxMiIKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uMWE5ZTA2YgotLS0gL2Rldi9udWxsCisrKyAiYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvU2NyaXB0cy9JbnNlcnQgZm9sZGVyIG5hbWVcMzAyXDIxMiIKQEAgLTAsMCArMSw2IEBACitpbXBvcnQgbWFjZnMKKworZnNzLCBvayA9IG1hY2ZzLkdldERpcmVjdG9yeSgpCitpZiBvazoKKwlpbXBvcnQgVworCVcuRnJvbnRXaW5kb3dJbnNlcnQoJyIlcyInICUgZnNzLmFzX3BhdGhuYW1lKCkpCmRpZmYgLS1naXQgYS9NYWMvQ29udHJpYi9QeUlERS1zcmMvdHJhY2UucHkgYi9NYWMvQ29udHJpYi9QeUlERS1zcmMvdHJhY2UucHkKbmV3IGZpbGUgbW9kZSAxMDA2NDQKaW5kZXggMDAwMDAwMC4uYzQ1YzY4NgotLS0gL2Rldi9udWxsCisrKyBiL01hYy9Db250cmliL1B5SURFLXNyYy90cmFjZS5weQpAQCAtMCwwICsxLDExOSBAQAorX192ZXJzaW9uX18gPSAiJElkJCIKKworaW1wb3J0IHN5cworZnJvbSB0aW1lIGltcG9ydCB0aW1lCisKK2NsYXNzIFRyYWNlOgorCWRlZiBfX2luaXRfXyhzZWxmKToKKwkJc2VsZi5kaXNwYXRjaCA9IHsKKwkJCSdjYWxsJzogc2VsZi50cmFjZV9kaXNwYXRjaF9jYWxsLAorCQkJJ3JldHVybic6IHNlbGYudHJhY2VfZGlzcGF0Y2hfcmV0dXJuLAorCQkJJ2V4Y2VwdGlvbic6IHNlbGYudHJhY2VfZGlzcGF0Y2hfZXhjZXB0aW9uLAorCQkJfQorCQlzZWxmLmN1cmZyYW1lID0gTm9uZQorCQlzZWxmLmRlcHRoID0gLTEKKwkJc2VsZi5zdGRvdXQgPSBzeXMuc3Rkb3V0CisKKwlkZWYgcnVuKHNlbGYsIGNtZCwgZ2xvYmFscyA9IE5vbmUsIGxvY2FscyA9IE5vbmUpOgorCQlpZiBnbG9iYWxzIGlzIE5vbmU6CisJCQlpbXBvcnQgX19tYWluX18KKwkJCWdsb2JhbHMgPSBfX21haW5fXy5fX2RpY3RfXworCQlpZiBsb2NhbHMgaXMgTm9uZToKKwkJCWxvY2FscyA9IGdsb2JhbHMKKwkJc3lzLnNldHByb2ZpbGUoc2VsZi50cmFjZV9kaXNwYXRjaCkKKwkJdHJ5OgorCQkJZXhlYyBjbWQgaW4gZ2xvYmFscywgbG9jYWxzCisJCWZpbmFsbHk6CisJCQlzeXMuc2V0cHJvZmlsZShOb25lKQorCisJZGVmIHJ1bmNhbGwoc2VsZiwgZnVuYywgKmFyZ3MpOgorCQlzeXMuc2V0cHJvZmlsZShzZWxmLnRyYWNlX2Rpc3BhdGNoKQorCQl0cnk6CisJCQlhcHBseShmdW5jLCBhcmdzKQorCQlmaW5hbGx5OgorCQkJc3lzLnNldHByb2ZpbGUoTm9uZSkKKworCWRlZiB0cmFjZV9kaXNwYXRjaChzZWxmLCBmcmFtZSwgZXZlbnQsIGFyZyk6CisJCWN1cnN0ZG91dCA9IHN5cy5zdGRvdXQKKwkJc3lzLnN0ZG91dCA9IHNlbGYuc3Rkb3V0CisJCXNlbGYuZGlzcGF0Y2hbZXZlbnRdKGZyYW1lLCBhcmcpCisJCXN5cy5zdGRvdXQgPSBjdXJzdGRvdXQKKworCWRlZiB0cmFjZV9kaXNwYXRjaF9jYWxsKHNlbGYsIGZyYW1lLCBhcmcpOgorCQlzZWxmLmRlcHRoID0gc2VsZi5kZXB0aCArIDEKKwkJc2VsZi5jdXJmcmFtZSA9IGZyYW1lCisJCWNvZGUgPSBmcmFtZS5mX2NvZGUKKwkJZnVuY25hbWUgPSBjb2RlLmNvX25hbWUKKwkJaWYgbm90IGZ1bmNuYW1lOgorCQkJZnVuY25hbWUgPSAnPGxhbWJkYT4nCisJCWZpbGVuYW1lID0gY29kZS5jb19maWxlbmFtZQorCQlsaW5lbm8gPSBmcmFtZS5mX2xpbmVubworCQlpZiBsaW5lbm8gPT0gLTE6CisJCQljb2RlID0gY29kZS5jb19jb2RlCisJCQlpZiBvcmQoY29kZVswXSkgPT0gMTI3OgkjIFNFVF9MSU5FTk8KKwkJCQlsaW5lbm8gPSBvcmQoY29kZVsxXSkgfCBvcmQoY29kZVsyXSkgPDwgOAorCQlwZnJhbWUgPSBmcmFtZS5mX2JhY2sKKwkJaWYgcGZyYW1lOgorCQkJcGxpbmVubyA9ICcgKCVkKScgJSBwZnJhbWUuZl9saW5lbm8KKwkJZWxzZToKKwkJCXBsaW5lbm8gPSAnJworCQlwcmludCAnJXM+ICVzOiVkICVzJXMnICUgKCcgJypzZWxmLmRlcHRoLGZpbGVuYW1lLGxpbmVubyxmdW5jbmFtZSxwbGluZW5vKQorCQlmcmFtZS5mX2xvY2Fsc1snX19zdGFydF90aW1lJ10gPSB0aW1lKCkKKworCWRlZiB0cmFjZV9kaXNwYXRjaF9yZXR1cm4oc2VsZiwgZnJhbWUsIGFyZyk6CisJCXRyeToKKwkJCXQgPSBmcmFtZS5mX2xvY2Fsc1snX19zdGFydF90aW1lJ10KKwkJZXhjZXB0IEtleUVycm9yOgorCQkJdCA9ICcnCisJCWVsc2U6CisJCQl0ID0gJyBbJS40Zl0nICUgKHRpbWUoKSAtIHQpCisJCWZ1bmNuYW1lID0gZnJhbWUuZl9jb2RlLmNvX25hbWUKKwkJc2VsZi5jdXJmcmFtZSA9IGZyYW1lLmZfYmFjaworCQlpZiBub3QgZnVuY25hbWU6CisJCQlmdW5jbmFtZSA9ICc8bGFtYmRhPicKKwkJZmlsZW5hbWUgPSBmcmFtZS5mX2NvZGUuY29fZmlsZW5hbWUKKwkJcHJpbnQgJyVzPCAlczolZCAlcyVzJyAlICgnICcqc2VsZi5kZXB0aCxmaWxlbmFtZSxmcmFtZS5mX2xpbmVubyxmdW5jbmFtZSx0KQorCQlzZWxmLmRlcHRoID0gc2VsZi5kZXB0aCAtIDEKKworCWRlZiB0cmFjZV9kaXNwYXRjaF9leGNlcHRpb24oc2VsZiwgZnJhbWUsIGFyZyk6CisJCXQgPSAnJworCQlpZiBmcmFtZSBpcyBub3Qgc2VsZi5jdXJmcmFtZToKKwkJCXRyeToKKwkJCQl0ID0gZnJhbWUuZl9sb2NhbHNbJ19fc3RhcnRfdGltZSddCisJCQlleGNlcHQgS2V5RXJyb3I6CisJCQkJcGFzcworCQkJZWxzZToKKwkJCQl0ID0gJyBbJS40Zl0nICUgKHRpbWUoKSAtIHQpCisJCQlzZWxmLmRlcHRoID0gc2VsZi5kZXB0aCAtIDEKKwkJCXNlbGYuY3VyZnJhbWUgPSBmcmFtZQorCQlmdW5jbmFtZSA9IGZyYW1lLmZfY29kZS5jb19uYW1lCisJCWlmIG5vdCBmdW5jbmFtZToKKwkJCWZ1bmNuYW1lID0gJzxsYW1iZGE+JworCQlmaWxlbmFtZSA9IGZyYW1lLmZfY29kZS5jb19maWxlbmFtZQorCQlwcmludCAnJXNFICVzOiVkICVzJXMnICUgKCcgJyooc2VsZi5kZXB0aCsxKSxmaWxlbmFtZSxmcmFtZS5mX2xpbmVubyxmdW5jbmFtZSx0KQorCisJZGVmIHNldF90cmFjZShzZWxmKToKKwkJdHJ5OgorCQkJcmFpc2UgJ3h5enp5JworCQlleGNlcHQ6CisJCQlmcmFtZSA9IHN5cy5leGNfdHJhY2ViYWNrLnRiX2ZyYW1lCisJCXdoaWxlIGZyYW1lLmZfY29kZS5jb19uYW1lICE9ICdzZXRfdHJhY2UnOgorCQkJZnJhbWUgPSBmcmFtZS5mX2JhY2sKKwkJZCA9IDAKKwkJd2hpbGUgZnJhbWU6CisJCQlkID0gZCArIDEKKwkJCWZyYW1lID0gZnJhbWUuZl9iYWNrCisJCXNlbGYuZGVwdGggPSBkCisJCXN5cy5zZXRwcm9maWxlKHNlbGYudHJhY2VfZGlzcGF0Y2gpCisKK2RlZiBydW4oY21kLCBnbG9iYWxzID0gTm9uZSwgbG9jYWxzID0gTm9uZSk6CisJVHJhY2UoKS5ydW4oY21kLCBnbG9iYWxzLCBsb2NhbHMpCisKK2RlZiBydW5jYWxsKCpmdW5jX2FyZ3MpOgorCWFwcGx5KFRyYWNlKCkucnVuY2FsbCwgZnVuY2FyZ3MpCisKK2RlZiBzZXRfdHJhY2UoKToKKwlUcmFjZSgpLnNldF90cmFjZSgpCisKK2RlZiB1bnNldF90cmFjZSgpOgorCXN5cy5zZXRwcm9maWxlKE5vbmUpCg==