IyByZWdyZXNzaW9uIHRlc3QgZm9yIFNBWCAyLjAKIyAkSWQkCgpmcm9tIHhtbC5zYXggaW1wb3J0IG1ha2VfcGFyc2VyLCBDb250ZW50SGFuZGxlciwgXAogICAgICAgICAgICAgICAgICAgIFNBWEV4Y2VwdGlvbiwgU0FYUmVhZGVyTm90QXZhaWxhYmxlLCBTQVhQYXJzZUV4Y2VwdGlvbgp0cnk6CiAgICBtYWtlX3BhcnNlcigpCmV4Y2VwdCBTQVhSZWFkZXJOb3RBdmFpbGFibGU6CiAgICAjIGRvbid0IHRyeSB0byB0ZXN0IHRoaXMgbW9kdWxlIGlmIHdlIGNhbm5vdCBjcmVhdGUgYSBwYXJzZXIKICAgIHJhaXNlIEltcG9ydEVycm9yKCJubyBYTUwgcGFyc2VycyBhdmFpbGFibGUiKQpmcm9tIHhtbC5zYXguc2F4dXRpbHMgaW1wb3J0IFhNTEdlbmVyYXRvciwgZXNjYXBlLCBxdW90ZWF0dHIsIFhNTEZpbHRlckJhc2UKZnJvbSB4bWwuc2F4LmV4cGF0cmVhZGVyIGltcG9ydCBjcmVhdGVfcGFyc2VyCmZyb20geG1sLnNheC54bWxyZWFkZXIgaW1wb3J0IElucHV0U291cmNlLCBBdHRyaWJ1dGVzSW1wbCwgQXR0cmlidXRlc05TSW1wbApmcm9tIGNTdHJpbmdJTyBpbXBvcnQgU3RyaW5nSU8KZnJvbSB0ZXN0X3N1cHBvcnQgaW1wb3J0IHZlcmlmeSwgdmVyYm9zZSwgVGVzdEZhaWxlZCwgZmluZGZpbGUKCiMgPT09PT0gVXRpbGl0aWVzCgp0ZXN0cyA9IDAKZmFpbHMgPSAwCgpkZWYgY29uZmlybShvdXRjb21lLCBuYW1lKToKICAgIGdsb2JhbCB0ZXN0cywgZmFpbHMKCiAgICB0ZXN0cyA9IHRlc3RzICsgMQogICAgaWYgb3V0Y29tZToKICAgICAgICBwcmludCAiUGFzc2VkIiwgbmFtZQogICAgZWxzZToKICAgICAgICBwcmludCAiRmFpbGVkIiwgbmFtZQogICAgICAgIGZhaWxzID0gZmFpbHMgKyAxCgpkZWYgdGVzdF9tYWtlX3BhcnNlcjIoKToKICAgIHRyeToKICAgICAgICAjIENyZWF0aW5nIHBhcnNlcnMgc2V2ZXJhbCB0aW1lcyBpbiBhIHJvdyBzaG91bGQgc3VjY2VlZC4KICAgICAgICAjIFRlc3RpbmcgdGhpcyBiZWNhdXNlIHRoZXJlIGhhdmUgYmVlbiBmYWlsdXJlcyBvZiB0aGlzIGtpbmQKICAgICAgICAjIGJlZm9yZS4KICAgICAgICBmcm9tIHhtbC5zYXggaW1wb3J0IG1ha2VfcGFyc2VyCiAgICAgICAgcCA9IG1ha2VfcGFyc2VyKCkKICAgICAgICBmcm9tIHhtbC5zYXggaW1wb3J0IG1ha2VfcGFyc2VyCiAgICAgICAgcCA9IG1ha2VfcGFyc2VyKCkKICAgICAgICBmcm9tIHhtbC5zYXggaW1wb3J0IG1ha2VfcGFyc2VyCiAgICAgICAgcCA9IG1ha2VfcGFyc2VyKCkKICAgICAgICBmcm9tIHhtbC5zYXggaW1wb3J0IG1ha2VfcGFyc2VyCiAgICAgICAgcCA9IG1ha2VfcGFyc2VyKCkKICAgICAgICBmcm9tIHhtbC5zYXggaW1wb3J0IG1ha2VfcGFyc2VyCiAgICAgICAgcCA9IG1ha2VfcGFyc2VyKCkKICAgICAgICBmcm9tIHhtbC5zYXggaW1wb3J0IG1ha2VfcGFyc2VyCiAgICAgICAgcCA9IG1ha2VfcGFyc2VyKCkKICAgIGV4Y2VwdDoKICAgICAgICByZXR1cm4gMAogICAgZWxzZToKICAgICAgICByZXR1cm4gcAoKCiMgPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09CiMKIyAgIHNheHV0aWxzIHRlc3RzCiMKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCiMgPT09PT0gZXNjYXBlCgpkZWYgdGVzdF9lc2NhcGVfYmFzaWMoKToKICAgIHJldHVybiBlc2NhcGUoIkRvbmFsZCBEdWNrICYgQ28iKSA9PSAiRG9uYWxkIER1Y2sgJmFtcDsgQ28iCgpkZWYgdGVzdF9lc2NhcGVfYWxsKCk6CiAgICByZXR1cm4gZXNjYXBlKCI8RG9uYWxkIER1Y2sgJiBDbz4iKSA9PSAiJmx0O0RvbmFsZCBEdWNrICZhbXA7IENvJmd0OyIKCmRlZiB0ZXN0X2VzY2FwZV9leHRyYSgpOgogICAgcmV0dXJuIGVzY2FwZSgiSGVpIHDlIGRlZyIsIHsi5SIgOiAiJmFyaW5nOyJ9KSA9PSAiSGVpIHAmYXJpbmc7IGRlZyIKCiMgPT09PT0gcXVvdGVhdHRyCgpkZWYgdGVzdF9xdW90ZWF0dHJfYmFzaWMoKToKICAgIHJldHVybiBxdW90ZWF0dHIoIkRvbmFsZCBEdWNrICYgQ28iKSA9PSAnIkRvbmFsZCBEdWNrICZhbXA7IENvIicKCmRlZiB0ZXN0X3NpbmdsZV9xdW90ZWF0dHIoKToKICAgIHJldHVybiAocXVvdGVhdHRyKCdJbmNsdWRlcyAiZG91YmxlIiBxdW90ZXMnKQogICAgICAgICAgICA9PSAnXCdJbmNsdWRlcyAiZG91YmxlIiBxdW90ZXNcJycpCgpkZWYgdGVzdF9kb3VibGVfcXVvdGVhdHRyKCk6CiAgICByZXR1cm4gKHF1b3RlYXR0cigiSW5jbHVkZXMgJ3NpbmdsZScgcXVvdGVzIikKICAgICAgICAgICAgPT0gIlwiSW5jbHVkZXMgJ3NpbmdsZScgcXVvdGVzXCIiKQoKZGVmIHRlc3Rfc2luZ2xlX2RvdWJsZV9xdW90ZWF0dHIoKToKICAgIHJldHVybiAocXVvdGVhdHRyKCJJbmNsdWRlcyAnc2luZ2xlJyBhbmQgXCJkb3VibGVcIiBxdW90ZXMiKQogICAgICAgICAgICA9PSAiXCJJbmNsdWRlcyAnc2luZ2xlJyBhbmQgJnF1b3Q7ZG91YmxlJnF1b3Q7IHF1b3Rlc1wiIikKCiMgPT09PT0gbWFrZV9wYXJzZXIKCmRlZiB0ZXN0X21ha2VfcGFyc2VyKCk6CiAgICB0cnk6CiAgICAgICAgIyBDcmVhdGluZyBhIHBhcnNlciBzaG91bGQgc3VjY2VlZCAtIGl0IHNob3VsZCBmYWxsIGJhY2sKICAgICAgICAjIHRvIHRoZSBleHBhdHJlYWRlcgogICAgICAgIHAgPSBtYWtlX3BhcnNlcihbJ3htbC5wYXJzZXJzLm5vX3N1Y2hfcGFyc2VyJ10pCiAgICBleGNlcHQ6CiAgICAgICAgcmV0dXJuIDAKICAgIGVsc2U6CiAgICAgICAgcmV0dXJuIHAKCgojID09PT09IFhNTEdlbmVyYXRvcgoKc3RhcnQgPSAnPD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iaXNvLTg4NTktMSI/PlxuJwoKZGVmIHRlc3RfeG1sZ2VuX2Jhc2ljKCk6CiAgICByZXN1bHQgPSBTdHJpbmdJTygpCiAgICBnZW4gPSBYTUxHZW5lcmF0b3IocmVzdWx0KQogICAgZ2VuLnN0YXJ0RG9jdW1lbnQoKQogICAgZ2VuLnN0YXJ0RWxlbWVudCgiZG9jIiwge30pCiAgICBnZW4uZW5kRWxlbWVudCgiZG9jIikKICAgIGdlbi5lbmREb2N1bWVudCgpCgogICAgcmV0dXJuIHJlc3VsdC5nZXR2YWx1ZSgpID09IHN0YXJ0ICsgIjxkb2M+PC9kb2M+IgoKZGVmIHRlc3RfeG1sZ2VuX2NvbnRlbnQoKToKICAgIHJlc3VsdCA9IFN0cmluZ0lPKCkKICAgIGdlbiA9IFhNTEdlbmVyYXRvcihyZXN1bHQpCgogICAgZ2VuLnN0YXJ0RG9jdW1lbnQoKQogICAgZ2VuLnN0YXJ0RWxlbWVudCgiZG9jIiwge30pCiAgICBnZW4uY2hhcmFjdGVycygiaHVoZWkiKQogICAgZ2VuLmVuZEVsZW1lbnQoImRvYyIpCiAgICBnZW4uZW5kRG9jdW1lbnQoKQoKICAgIHJldHVybiByZXN1bHQuZ2V0dmFsdWUoKSA9PSBzdGFydCArICI8ZG9jPmh1aGVpPC9kb2M+IgoKZGVmIHRlc3RfeG1sZ2VuX3BpKCk6CiAgICByZXN1bHQgPSBTdHJpbmdJTygpCiAgICBnZW4gPSBYTUxHZW5lcmF0b3IocmVzdWx0KQoKICAgIGdlbi5zdGFydERvY3VtZW50KCkKICAgIGdlbi5wcm9jZXNzaW5nSW5zdHJ1Y3Rpb24oInRlc3QiLCAiZGF0YSIpCiAgICBnZW4uc3RhcnRFbGVtZW50KCJkb2MiLCB7fSkKICAgIGdlbi5lbmRFbGVtZW50KCJkb2MiKQogICAgZ2VuLmVuZERvY3VtZW50KCkKCiAgICByZXR1cm4gcmVzdWx0LmdldHZhbHVlKCkgPT0gc3RhcnQgKyAiPD90ZXN0IGRhdGE/Pjxkb2M+PC9kb2M+IgoKZGVmIHRlc3RfeG1sZ2VuX2NvbnRlbnRfZXNjYXBlKCk6CiAgICByZXN1bHQgPSBTdHJpbmdJTygpCiAgICBnZW4gPSBYTUxHZW5lcmF0b3IocmVzdWx0KQoKICAgIGdlbi5zdGFydERvY3VtZW50KCkKICAgIGdlbi5zdGFydEVsZW1lbnQoImRvYyIsIHt9KQogICAgZ2VuLmNoYXJhY3RlcnMoIjxodWhlaSYiKQogICAgZ2VuLmVuZEVsZW1lbnQoImRvYyIpCiAgICBnZW4uZW5kRG9jdW1lbnQoKQoKICAgIHJldHVybiByZXN1bHQuZ2V0dmFsdWUoKSA9PSBzdGFydCArICI8ZG9jPiZsdDtodWhlaSZhbXA7PC9kb2M+IgoKZGVmIHRlc3RfeG1sZ2VuX2lnbm9yYWJsZSgpOgogICAgcmVzdWx0ID0gU3RyaW5nSU8oKQogICAgZ2VuID0gWE1MR2VuZXJhdG9yKHJlc3VsdCkKCiAgICBnZW4uc3RhcnREb2N1bWVudCgpCiAgICBnZW4uc3RhcnRFbGVtZW50KCJkb2MiLCB7fSkKICAgIGdlbi5pZ25vcmFibGVXaGl0ZXNwYWNlKCIgIikKICAgIGdlbi5lbmRFbGVtZW50KCJkb2MiKQogICAgZ2VuLmVuZERvY3VtZW50KCkKCiAgICByZXR1cm4gcmVzdWx0LmdldHZhbHVlKCkgPT0gc3RhcnQgKyAiPGRvYz4gPC9kb2M+IgoKbnNfdXJpID0gImh0dHA6Ly93d3cucHl0aG9uLm9yZy94bWwtbnMvc2F4dGVzdC8iCgpkZWYgdGVzdF94bWxnZW5fbnMoKToKICAgIHJlc3VsdCA9IFN0cmluZ0lPKCkKICAgIGdlbiA9IFhNTEdlbmVyYXRvcihyZXN1bHQpCgogICAgZ2VuLnN0YXJ0RG9jdW1lbnQoKQogICAgZ2VuLnN0YXJ0UHJlZml4TWFwcGluZygibnMxIiwgbnNfdXJpKQogICAgZ2VuLnN0YXJ0RWxlbWVudE5TKChuc191cmksICJkb2MiKSwgIm5zMTpkb2MiLCB7fSkKICAgICMgYWRkIGFuIHVucXVhbGlmaWVkIG5hbWUKICAgIGdlbi5zdGFydEVsZW1lbnROUygoTm9uZSwgInVkb2MiKSwgTm9uZSwge30pCiAgICBnZW4uZW5kRWxlbWVudE5TKChOb25lLCAidWRvYyIpLCBOb25lKQogICAgZ2VuLmVuZEVsZW1lbnROUygobnNfdXJpLCAiZG9jIiksICJuczE6ZG9jIikKICAgIGdlbi5lbmRQcmVmaXhNYXBwaW5nKCJuczEiKQogICAgZ2VuLmVuZERvY3VtZW50KCkKCiAgICByZXR1cm4gcmVzdWx0LmdldHZhbHVlKCkgPT0gc3RhcnQgKyBcCiAgICAgICAgICAgKCc8bnMxOmRvYyB4bWxuczpuczE9IiVzIj48dWRvYz48L3Vkb2M+PC9uczE6ZG9jPicgJQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5zX3VyaSkKCiMgPT09PT0gWE1MRmlsdGVyQmFzZQoKZGVmIHRlc3RfZmlsdGVyX2Jhc2ljKCk6CiAgICByZXN1bHQgPSBTdHJpbmdJTygpCiAgICBnZW4gPSBYTUxHZW5lcmF0b3IocmVzdWx0KQogICAgZmlsdGVyID0gWE1MRmlsdGVyQmFzZSgpCiAgICBmaWx0ZXIuc2V0Q29udGVudEhhbmRsZXIoZ2VuKQoKICAgIGZpbHRlci5zdGFydERvY3VtZW50KCkKICAgIGZpbHRlci5zdGFydEVsZW1lbnQoImRvYyIsIHt9KQogICAgZmlsdGVyLmNoYXJhY3RlcnMoImNvbnRlbnQiKQogICAgZmlsdGVyLmlnbm9yYWJsZVdoaXRlc3BhY2UoIiAiKQogICAgZmlsdGVyLmVuZEVsZW1lbnQoImRvYyIpCiAgICBmaWx0ZXIuZW5kRG9jdW1lbnQoKQoKICAgIHJldHVybiByZXN1bHQuZ2V0dmFsdWUoKSA9PSBzdGFydCArICI8ZG9jPmNvbnRlbnQgPC9kb2M+IgoKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIwojICAgZXhwYXRyZWFkZXIgdGVzdHMKIwojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKIyA9PT09PSBYTUxSZWFkZXIgc3VwcG9ydAoKZGVmIHRlc3RfZXhwYXRfZmlsZSgpOgogICAgcGFyc2VyID0gY3JlYXRlX3BhcnNlcigpCiAgICByZXN1bHQgPSBTdHJpbmdJTygpCiAgICB4bWxnZW4gPSBYTUxHZW5lcmF0b3IocmVzdWx0KQoKICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcih4bWxnZW4pCiAgICBwYXJzZXIucGFyc2Uob3BlbihmaW5kZmlsZSgidGVzdC54bWwiKSkpCgogICAgcmV0dXJuIHJlc3VsdC5nZXR2YWx1ZSgpID09IHhtbF90ZXN0X291dAoKIyA9PT09PSBEVERIYW5kbGVyIHN1cHBvcnQKCmNsYXNzIFRlc3REVERIYW5kbGVyOgoKICAgIGRlZiBfX2luaXRfXyhzZWxmKToKICAgICAgICBzZWxmLl9ub3RhdGlvbnMgPSBbXQogICAgICAgIHNlbGYuX2VudGl0aWVzICA9IFtdCgogICAgZGVmIG5vdGF0aW9uRGVjbChzZWxmLCBuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQpOgogICAgICAgIHNlbGYuX25vdGF0aW9ucy5hcHBlbmQoKG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCkpCgogICAgZGVmIHVucGFyc2VkRW50aXR5RGVjbChzZWxmLCBuYW1lLCBwdWJsaWNJZCwgc3lzdGVtSWQsIG5kYXRhKToKICAgICAgICBzZWxmLl9lbnRpdGllcy5hcHBlbmQoKG5hbWUsIHB1YmxpY0lkLCBzeXN0ZW1JZCwgbmRhdGEpKQoKZGVmIHRlc3RfZXhwYXRfZHRkaGFuZGxlcigpOgogICAgcGFyc2VyID0gY3JlYXRlX3BhcnNlcigpCiAgICBoYW5kbGVyID0gVGVzdERUREhhbmRsZXIoKQogICAgcGFyc2VyLnNldERUREhhbmRsZXIoaGFuZGxlcikKCiAgICBwYXJzZXIuZmVlZCgnPCFET0NUWVBFIGRvYyBbXG4nKQogICAgcGFyc2VyLmZlZWQoJyAgPCFFTlRJVFkgaW1nIFNZU1RFTSAiZXhwYXQuZ2lmIiBOREFUQSBHSUY+XG4nKQogICAgcGFyc2VyLmZlZWQoJyAgPCFOT1RBVElPTiBHSUYgUFVCTElDICItLy9Db21wdVNlcnZlLy9OT1RBVElPTiBHcmFwaGljcyBJbnRlcmNoYW5nZSBGb3JtYXQgODlhLy9FTiI+XG4nKQogICAgcGFyc2VyLmZlZWQoJ10+XG4nKQogICAgcGFyc2VyLmZlZWQoJzxkb2M+PC9kb2M+JykKICAgIHBhcnNlci5jbG9zZSgpCgogICAgcmV0dXJuIGhhbmRsZXIuX25vdGF0aW9ucyA9PSBbKCJHSUYiLCAiLS8vQ29tcHVTZXJ2ZS8vTk9UQVRJT04gR3JhcGhpY3MgSW50ZXJjaGFuZ2UgRm9ybWF0IDg5YS8vRU4iLCBOb25lKV0gYW5kIFwKICAgICAgICAgICBoYW5kbGVyLl9lbnRpdGllcyA9PSBbKCJpbWciLCBOb25lLCAiZXhwYXQuZ2lmIiwgIkdJRiIpXQoKIyA9PT09PSBFbnRpdHlSZXNvbHZlciBzdXBwb3J0CgpjbGFzcyBUZXN0RW50aXR5UmVzb2x2ZXI6CgogICAgZGVmIHJlc29sdmVFbnRpdHkoc2VsZiwgcHVibGljSWQsIHN5c3RlbUlkKToKICAgICAgICBpbnBzcmMgPSBJbnB1dFNvdXJjZSgpCiAgICAgICAgaW5wc3JjLnNldEJ5dGVTdHJlYW0oU3RyaW5nSU8oIjxlbnRpdHkvPiIpKQogICAgICAgIHJldHVybiBpbnBzcmMKCmRlZiB0ZXN0X2V4cGF0X2VudGl0eXJlc29sdmVyKCk6CiAgICBwYXJzZXIgPSBjcmVhdGVfcGFyc2VyKCkKICAgIHBhcnNlci5zZXRFbnRpdHlSZXNvbHZlcihUZXN0RW50aXR5UmVzb2x2ZXIoKSkKICAgIHJlc3VsdCA9IFN0cmluZ0lPKCkKICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcihYTUxHZW5lcmF0b3IocmVzdWx0KSkKCiAgICBwYXJzZXIuZmVlZCgnPCFET0NUWVBFIGRvYyBbXG4nKQogICAgcGFyc2VyLmZlZWQoJyAgPCFFTlRJVFkgdGVzdCBTWVNURU0gIndoYXRldmVyIj5cbicpCiAgICBwYXJzZXIuZmVlZCgnXT5cbicpCiAgICBwYXJzZXIuZmVlZCgnPGRvYz4mdGVzdDs8L2RvYz4nKQogICAgcGFyc2VyLmNsb3NlKCkKCiAgICByZXR1cm4gcmVzdWx0LmdldHZhbHVlKCkgPT0gc3RhcnQgKyAiPGRvYz48ZW50aXR5PjwvZW50aXR5PjwvZG9jPiIKCiMgPT09PT0gQXR0cmlidXRlcyBzdXBwb3J0CgpjbGFzcyBBdHRyR2F0aGVyZXIoQ29udGVudEhhbmRsZXIpOgoKICAgIGRlZiBzdGFydEVsZW1lbnQoc2VsZiwgbmFtZSwgYXR0cnMpOgogICAgICAgIHNlbGYuX2F0dHJzID0gYXR0cnMKCiAgICBkZWYgc3RhcnRFbGVtZW50TlMoc2VsZiwgbmFtZSwgcW5hbWUsIGF0dHJzKToKICAgICAgICBzZWxmLl9hdHRycyA9IGF0dHJzCgpkZWYgdGVzdF9leHBhdF9hdHRyc19lbXB0eSgpOgogICAgcGFyc2VyID0gY3JlYXRlX3BhcnNlcigpCiAgICBnYXRoZXIgPSBBdHRyR2F0aGVyZXIoKQogICAgcGFyc2VyLnNldENvbnRlbnRIYW5kbGVyKGdhdGhlcikKCiAgICBwYXJzZXIuZmVlZCgiPGRvYy8+IikKICAgIHBhcnNlci5jbG9zZSgpCgogICAgcmV0dXJuIHZlcmlmeV9lbXB0eV9hdHRycyhnYXRoZXIuX2F0dHJzKQoKZGVmIHRlc3RfZXhwYXRfYXR0cnNfd2F0dHIoKToKICAgIHBhcnNlciA9IGNyZWF0ZV9wYXJzZXIoKQogICAgZ2F0aGVyID0gQXR0ckdhdGhlcmVyKCkKICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcihnYXRoZXIpCgogICAgcGFyc2VyLmZlZWQoIjxkb2MgYXR0cj0ndmFsJy8+IikKICAgIHBhcnNlci5jbG9zZSgpCgogICAgcmV0dXJuIHZlcmlmeV9hdHRyc193YXR0cihnYXRoZXIuX2F0dHJzKQoKZGVmIHRlc3RfZXhwYXRfbnNhdHRyc19lbXB0eSgpOgogICAgcGFyc2VyID0gY3JlYXRlX3BhcnNlcigxKQogICAgZ2F0aGVyID0gQXR0ckdhdGhlcmVyKCkKICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcihnYXRoZXIpCgogICAgcGFyc2VyLmZlZWQoIjxkb2MvPiIpCiAgICBwYXJzZXIuY2xvc2UoKQoKICAgIHJldHVybiB2ZXJpZnlfZW1wdHlfbnNhdHRycyhnYXRoZXIuX2F0dHJzKQoKZGVmIHRlc3RfZXhwYXRfbnNhdHRyc193YXR0cigpOgogICAgcGFyc2VyID0gY3JlYXRlX3BhcnNlcigxKQogICAgZ2F0aGVyID0gQXR0ckdhdGhlcmVyKCkKICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcihnYXRoZXIpCgogICAgcGFyc2VyLmZlZWQoIjxkb2MgeG1sbnM6bnM9JyVzJyBuczphdHRyPSd2YWwnLz4iICUgbnNfdXJpKQogICAgcGFyc2VyLmNsb3NlKCkKCiAgICBhdHRycyA9IGdhdGhlci5fYXR0cnMKCiAgICByZXR1cm4gYXR0cnMuZ2V0TGVuZ3RoKCkgPT0gMSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldE5hbWVzKCkgPT0gWyhuc191cmksICJhdHRyIildIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0UU5hbWVzKCkgPT0gW10gYW5kIFwKICAgICAgICAgICBsZW4oYXR0cnMpID09IDEgYW5kIFwKICAgICAgICAgICBhdHRycy5oYXNfa2V5KChuc191cmksICJhdHRyIikpIGFuZCBcCiAgICAgICAgICAgYXR0cnMua2V5cygpID09IFsobnNfdXJpLCAiYXR0ciIpXSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldCgobnNfdXJpLCAiYXR0ciIpKSA9PSAidmFsIiBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldCgobnNfdXJpLCAiYXR0ciIpLCAyNSkgPT0gInZhbCIgYW5kIFwKICAgICAgICAgICBhdHRycy5pdGVtcygpID09IFsoKG5zX3VyaSwgImF0dHIiKSwgInZhbCIpXSBhbmQgXAogICAgICAgICAgIGF0dHJzLnZhbHVlcygpID09IFsidmFsIl0gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRWYWx1ZSgobnNfdXJpLCAiYXR0ciIpKSA9PSAidmFsIiBhbmQgXAogICAgICAgICAgIGF0dHJzWyhuc191cmksICJhdHRyIildID09ICJ2YWwiCgojID09PT09IElucHV0U291cmNlIHN1cHBvcnQKCnhtbF90ZXN0X291dCA9IG9wZW4oZmluZGZpbGUoInRlc3QueG1sLm91dCIpKS5yZWFkKCkKCmRlZiB0ZXN0X2V4cGF0X2lucHNvdXJjZV9maWxlbmFtZSgpOgogICAgcGFyc2VyID0gY3JlYXRlX3BhcnNlcigpCiAgICByZXN1bHQgPSBTdHJpbmdJTygpCiAgICB4bWxnZW4gPSBYTUxHZW5lcmF0b3IocmVzdWx0KQoKICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcih4bWxnZW4pCiAgICBwYXJzZXIucGFyc2UoZmluZGZpbGUoInRlc3QueG1sIikpCgogICAgcmV0dXJuIHJlc3VsdC5nZXR2YWx1ZSgpID09IHhtbF90ZXN0X291dAoKZGVmIHRlc3RfZXhwYXRfaW5wc291cmNlX3N5c2lkKCk6CiAgICBwYXJzZXIgPSBjcmVhdGVfcGFyc2VyKCkKICAgIHJlc3VsdCA9IFN0cmluZ0lPKCkKICAgIHhtbGdlbiA9IFhNTEdlbmVyYXRvcihyZXN1bHQpCgogICAgcGFyc2VyLnNldENvbnRlbnRIYW5kbGVyKHhtbGdlbikKICAgIHBhcnNlci5wYXJzZShJbnB1dFNvdXJjZShmaW5kZmlsZSgidGVzdC54bWwiKSkpCgogICAgcmV0dXJuIHJlc3VsdC5nZXR2YWx1ZSgpID09IHhtbF90ZXN0X291dAoKZGVmIHRlc3RfZXhwYXRfaW5wc291cmNlX3N0cmVhbSgpOgogICAgcGFyc2VyID0gY3JlYXRlX3BhcnNlcigpCiAgICByZXN1bHQgPSBTdHJpbmdJTygpCiAgICB4bWxnZW4gPSBYTUxHZW5lcmF0b3IocmVzdWx0KQoKICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcih4bWxnZW4pCiAgICBpbnBzcmMgPSBJbnB1dFNvdXJjZSgpCiAgICBpbnBzcmMuc2V0Qnl0ZVN0cmVhbShvcGVuKGZpbmRmaWxlKCJ0ZXN0LnhtbCIpKSkKICAgIHBhcnNlci5wYXJzZShpbnBzcmMpCgogICAgcmV0dXJuIHJlc3VsdC5nZXR2YWx1ZSgpID09IHhtbF90ZXN0X291dAoKIyA9PT09PSBJbmNyZW1lbnRhbFBhcnNlciBzdXBwb3J0CgpkZWYgdGVzdF9leHBhdF9pbmNyZW1lbnRhbCgpOgogICAgcmVzdWx0ID0gU3RyaW5nSU8oKQogICAgeG1sZ2VuID0gWE1MR2VuZXJhdG9yKHJlc3VsdCkKICAgIHBhcnNlciA9IGNyZWF0ZV9wYXJzZXIoKQogICAgcGFyc2VyLnNldENvbnRlbnRIYW5kbGVyKHhtbGdlbikKCiAgICBwYXJzZXIuZmVlZCgiPGRvYz4iKQogICAgcGFyc2VyLmZlZWQoIjwvZG9jPiIpCiAgICBwYXJzZXIuY2xvc2UoKQoKICAgIHJldHVybiByZXN1bHQuZ2V0dmFsdWUoKSA9PSBzdGFydCArICI8ZG9jPjwvZG9jPiIKCmRlZiB0ZXN0X2V4cGF0X2luY3JlbWVudGFsX3Jlc2V0KCk6CiAgICByZXN1bHQgPSBTdHJpbmdJTygpCiAgICB4bWxnZW4gPSBYTUxHZW5lcmF0b3IocmVzdWx0KQogICAgcGFyc2VyID0gY3JlYXRlX3BhcnNlcigpCiAgICBwYXJzZXIuc2V0Q29udGVudEhhbmRsZXIoeG1sZ2VuKQoKICAgIHBhcnNlci5mZWVkKCI8ZG9jPiIpCiAgICBwYXJzZXIuZmVlZCgidGV4dCIpCgogICAgcmVzdWx0ID0gU3RyaW5nSU8oKQogICAgeG1sZ2VuID0gWE1MR2VuZXJhdG9yKHJlc3VsdCkKICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcih4bWxnZW4pCiAgICBwYXJzZXIucmVzZXQoKQoKICAgIHBhcnNlci5mZWVkKCI8ZG9jPiIpCiAgICBwYXJzZXIuZmVlZCgidGV4dCIpCiAgICBwYXJzZXIuZmVlZCgiPC9kb2M+IikKICAgIHBhcnNlci5jbG9zZSgpCgogICAgcmV0dXJuIHJlc3VsdC5nZXR2YWx1ZSgpID09IHN0YXJ0ICsgIjxkb2M+dGV4dDwvZG9jPiIKCiMgPT09PT0gTG9jYXRvciBzdXBwb3J0CgpkZWYgdGVzdF9leHBhdF9sb2NhdG9yX25vaW5mbygpOgogICAgcmVzdWx0ID0gU3RyaW5nSU8oKQogICAgeG1sZ2VuID0gWE1MR2VuZXJhdG9yKHJlc3VsdCkKICAgIHBhcnNlciA9IGNyZWF0ZV9wYXJzZXIoKQogICAgcGFyc2VyLnNldENvbnRlbnRIYW5kbGVyKHhtbGdlbikKCiAgICBwYXJzZXIuZmVlZCgiPGRvYz4iKQogICAgcGFyc2VyLmZlZWQoIjwvZG9jPiIpCiAgICBwYXJzZXIuY2xvc2UoKQoKICAgIHJldHVybiBwYXJzZXIuZ2V0U3lzdGVtSWQoKSBpcyBOb25lIGFuZCBcCiAgICAgICAgICAgcGFyc2VyLmdldFB1YmxpY0lkKCkgaXMgTm9uZSBhbmQgXAogICAgICAgICAgIHBhcnNlci5nZXRMaW5lTnVtYmVyKCkgPT0gMQoKZGVmIHRlc3RfZXhwYXRfbG9jYXRvcl93aXRoaW5mbygpOgogICAgcmVzdWx0ID0gU3RyaW5nSU8oKQogICAgeG1sZ2VuID0gWE1MR2VuZXJhdG9yKHJlc3VsdCkKICAgIHBhcnNlciA9IGNyZWF0ZV9wYXJzZXIoKQogICAgcGFyc2VyLnNldENvbnRlbnRIYW5kbGVyKHhtbGdlbikKICAgIHBhcnNlci5wYXJzZShmaW5kZmlsZSgidGVzdC54bWwiKSkKCiAgICByZXR1cm4gcGFyc2VyLmdldFN5c3RlbUlkKCkgPT0gZmluZGZpbGUoInRlc3QueG1sIikgYW5kIFwKICAgICAgICAgICBwYXJzZXIuZ2V0UHVibGljSWQoKSBpcyBOb25lCgoKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KIwojICAgZXJyb3IgcmVwb3J0aW5nCiMKIyA9PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT0KCmRlZiB0ZXN0X2V4cGF0X2lucHNvdXJjZV9sb2NhdGlvbigpOgogICAgcGFyc2VyID0gY3JlYXRlX3BhcnNlcigpCiAgICBwYXJzZXIuc2V0Q29udGVudEhhbmRsZXIoQ29udGVudEhhbmRsZXIoKSkgIyBkbyBub3RoaW5nCiAgICBzb3VyY2UgPSBJbnB1dFNvdXJjZSgpCiAgICBzb3VyY2Uuc2V0Qnl0ZVN0cmVhbShTdHJpbmdJTygiPGZvbyBiYXIgZm9vYmFyPiIpKSAgICNpbGwtZm9ybWVkCiAgICBuYW1lID0gImEgZmlsZSBuYW1lIgogICAgc291cmNlLnNldFN5c3RlbUlkKG5hbWUpCiAgICB0cnk6CiAgICAgICAgcGFyc2VyLnBhcnNlKHNvdXJjZSkKICAgIGV4Y2VwdCBTQVhFeGNlcHRpb24sIGU6CiAgICAgICAgcmV0dXJuIGUuZ2V0U3lzdGVtSWQoKSA9PSBuYW1lCgpkZWYgdGVzdF9leHBhdF9pbmNvbXBsZXRlKCk6CiAgICBwYXJzZXIgPSBjcmVhdGVfcGFyc2VyKCkKICAgIHBhcnNlci5zZXRDb250ZW50SGFuZGxlcihDb250ZW50SGFuZGxlcigpKSAjIGRvIG5vdGhpbmcKICAgIHRyeToKICAgICAgICBwYXJzZXIucGFyc2UoU3RyaW5nSU8oIjxmb28+IikpCiAgICBleGNlcHQgU0FYUGFyc2VFeGNlcHRpb246CiAgICAgICAgcmV0dXJuIDEgIyBvaywgZXJyb3IgZm91bmQKICAgIGVsc2U6CiAgICAgICAgcmV0dXJuIDAKCgojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQojCiMgICB4bWxyZWFkZXIgdGVzdHMKIwojID09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQoKIyA9PT09PSBBdHRyaWJ1dGVzSW1wbAoKZGVmIHZlcmlmeV9lbXB0eV9hdHRycyhhdHRycyk6CiAgICB0cnk6CiAgICAgICAgYXR0cnMuZ2V0VmFsdWUoImF0dHIiKQogICAgICAgIGd2ayA9IDAKICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICBndmsgPSAxCgogICAgdHJ5OgogICAgICAgIGF0dHJzLmdldFZhbHVlQnlRTmFtZSgiYXR0ciIpCiAgICAgICAgZ3ZxayA9IDAKICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICBndnFrID0gMQoKICAgIHRyeToKICAgICAgICBhdHRycy5nZXROYW1lQnlRTmFtZSgiYXR0ciIpCiAgICAgICAgZ25xayA9IDAKICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICBnbnFrID0gMQoKICAgIHRyeToKICAgICAgICBhdHRycy5nZXRRTmFtZUJ5TmFtZSgiYXR0ciIpCiAgICAgICAgZ3FuayA9IDAKICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICBncW5rID0gMQoKICAgIHRyeToKICAgICAgICBhdHRyc1siYXR0ciJdCiAgICAgICAgZ2lrID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGdpayA9IDEKCiAgICByZXR1cm4gYXR0cnMuZ2V0TGVuZ3RoKCkgPT0gMCBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldE5hbWVzKCkgPT0gW10gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRRTmFtZXMoKSA9PSBbXSBhbmQgXAogICAgICAgICAgIGxlbihhdHRycykgPT0gMCBhbmQgXAogICAgICAgICAgIG5vdCBhdHRycy5oYXNfa2V5KCJhdHRyIikgYW5kIFwKICAgICAgICAgICBhdHRycy5rZXlzKCkgPT0gW10gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXQoImF0dHJzIikgaXMgTm9uZSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldCgiYXR0cnMiLCAyNSkgPT0gMjUgYW5kIFwKICAgICAgICAgICBhdHRycy5pdGVtcygpID09IFtdIGFuZCBcCiAgICAgICAgICAgYXR0cnMudmFsdWVzKCkgPT0gW10gYW5kIFwKICAgICAgICAgICBndmsgYW5kIGd2cWsgYW5kIGducWsgYW5kIGdpayBhbmQgZ3FuawoKZGVmIHZlcmlmeV9hdHRyc193YXR0cihhdHRycyk6CiAgICByZXR1cm4gYXR0cnMuZ2V0TGVuZ3RoKCkgPT0gMSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldE5hbWVzKCkgPT0gWyJhdHRyIl0gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRRTmFtZXMoKSA9PSBbImF0dHIiXSBhbmQgXAogICAgICAgICAgIGxlbihhdHRycykgPT0gMSBhbmQgXAogICAgICAgICAgIGF0dHJzLmhhc19rZXkoImF0dHIiKSBhbmQgXAogICAgICAgICAgIGF0dHJzLmtleXMoKSA9PSBbImF0dHIiXSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldCgiYXR0ciIpID09ICJ2YWwiIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0KCJhdHRyIiwgMjUpID09ICJ2YWwiIGFuZCBcCiAgICAgICAgICAgYXR0cnMuaXRlbXMoKSA9PSBbKCJhdHRyIiwgInZhbCIpXSBhbmQgXAogICAgICAgICAgIGF0dHJzLnZhbHVlcygpID09IFsidmFsIl0gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRWYWx1ZSgiYXR0ciIpID09ICJ2YWwiIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0VmFsdWVCeVFOYW1lKCJhdHRyIikgPT0gInZhbCIgYW5kIFwKICAgICAgICAgICBhdHRycy5nZXROYW1lQnlRTmFtZSgiYXR0ciIpID09ICJhdHRyIiBhbmQgXAogICAgICAgICAgIGF0dHJzWyJhdHRyIl0gPT0gInZhbCIgYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRRTmFtZUJ5TmFtZSgiYXR0ciIpID09ICJhdHRyIgoKZGVmIHRlc3RfYXR0cnNfZW1wdHkoKToKICAgIHJldHVybiB2ZXJpZnlfZW1wdHlfYXR0cnMoQXR0cmlidXRlc0ltcGwoe30pKQoKZGVmIHRlc3RfYXR0cnNfd2F0dHIoKToKICAgIHJldHVybiB2ZXJpZnlfYXR0cnNfd2F0dHIoQXR0cmlidXRlc0ltcGwoeyJhdHRyIiA6ICJ2YWwifSkpCgojID09PT09IEF0dHJpYnV0ZXNJbXBsCgpkZWYgdmVyaWZ5X2VtcHR5X25zYXR0cnMoYXR0cnMpOgogICAgdHJ5OgogICAgICAgIGF0dHJzLmdldFZhbHVlKChuc191cmksICJhdHRyIikpCiAgICAgICAgZ3ZrID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGd2ayA9IDEKCiAgICB0cnk6CiAgICAgICAgYXR0cnMuZ2V0VmFsdWVCeVFOYW1lKCJuczphdHRyIikKICAgICAgICBndnFrID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGd2cWsgPSAxCgogICAgdHJ5OgogICAgICAgIGF0dHJzLmdldE5hbWVCeVFOYW1lKCJuczphdHRyIikKICAgICAgICBnbnFrID0gMAogICAgZXhjZXB0IEtleUVycm9yOgogICAgICAgIGducWsgPSAxCgogICAgdHJ5OgogICAgICAgIGF0dHJzLmdldFFOYW1lQnlOYW1lKChuc191cmksICJhdHRyIikpCiAgICAgICAgZ3FuayA9IDAKICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICBncW5rID0gMQoKICAgIHRyeToKICAgICAgICBhdHRyc1sobnNfdXJpLCAiYXR0ciIpXQogICAgICAgIGdpayA9IDAKICAgIGV4Y2VwdCBLZXlFcnJvcjoKICAgICAgICBnaWsgPSAxCgogICAgcmV0dXJuIGF0dHJzLmdldExlbmd0aCgpID09IDAgYW5kIFwKICAgICAgICAgICBhdHRycy5nZXROYW1lcygpID09IFtdIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0UU5hbWVzKCkgPT0gW10gYW5kIFwKICAgICAgICAgICBsZW4oYXR0cnMpID09IDAgYW5kIFwKICAgICAgICAgICBub3QgYXR0cnMuaGFzX2tleSgobnNfdXJpLCAiYXR0ciIpKSBhbmQgXAogICAgICAgICAgIGF0dHJzLmtleXMoKSA9PSBbXSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldCgobnNfdXJpLCAiYXR0ciIpKSBpcyBOb25lIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0KChuc191cmksICJhdHRyIiksIDI1KSA9PSAyNSBhbmQgXAogICAgICAgICAgIGF0dHJzLml0ZW1zKCkgPT0gW10gYW5kIFwKICAgICAgICAgICBhdHRycy52YWx1ZXMoKSA9PSBbXSBhbmQgXAogICAgICAgICAgIGd2ayBhbmQgZ3ZxayBhbmQgZ25xayBhbmQgZ2lrIGFuZCBncW5rCgpkZWYgdGVzdF9uc2F0dHJzX2VtcHR5KCk6CiAgICByZXR1cm4gdmVyaWZ5X2VtcHR5X25zYXR0cnMoQXR0cmlidXRlc05TSW1wbCh7fSwge30pKQoKZGVmIHRlc3RfbnNhdHRyc193YXR0cigpOgogICAgYXR0cnMgPSBBdHRyaWJ1dGVzTlNJbXBsKHsobnNfdXJpLCAiYXR0ciIpIDogInZhbCJ9LAogICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsobnNfdXJpLCAiYXR0ciIpIDogIm5zOmF0dHIifSkKCiAgICByZXR1cm4gYXR0cnMuZ2V0TGVuZ3RoKCkgPT0gMSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldE5hbWVzKCkgPT0gWyhuc191cmksICJhdHRyIildIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0UU5hbWVzKCkgPT0gWyJuczphdHRyIl0gYW5kIFwKICAgICAgICAgICBsZW4oYXR0cnMpID09IDEgYW5kIFwKICAgICAgICAgICBhdHRycy5oYXNfa2V5KChuc191cmksICJhdHRyIikpIGFuZCBcCiAgICAgICAgICAgYXR0cnMua2V5cygpID09IFsobnNfdXJpLCAiYXR0ciIpXSBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldCgobnNfdXJpLCAiYXR0ciIpKSA9PSAidmFsIiBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldCgobnNfdXJpLCAiYXR0ciIpLCAyNSkgPT0gInZhbCIgYW5kIFwKICAgICAgICAgICBhdHRycy5pdGVtcygpID09IFsoKG5zX3VyaSwgImF0dHIiKSwgInZhbCIpXSBhbmQgXAogICAgICAgICAgIGF0dHJzLnZhbHVlcygpID09IFsidmFsIl0gYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRWYWx1ZSgobnNfdXJpLCAiYXR0ciIpKSA9PSAidmFsIiBhbmQgXAogICAgICAgICAgIGF0dHJzLmdldFZhbHVlQnlRTmFtZSgibnM6YXR0ciIpID09ICJ2YWwiIGFuZCBcCiAgICAgICAgICAgYXR0cnMuZ2V0TmFtZUJ5UU5hbWUoIm5zOmF0dHIiKSA9PSAobnNfdXJpLCAiYXR0ciIpIGFuZCBcCiAgICAgICAgICAgYXR0cnNbKG5zX3VyaSwgImF0dHIiKV0gPT0gInZhbCIgYW5kIFwKICAgICAgICAgICBhdHRycy5nZXRRTmFtZUJ5TmFtZSgobnNfdXJpLCAiYXR0ciIpKSA9PSAibnM6YXR0ciIKCgojID09PT09IE1haW4gcHJvZ3JhbQoKZGVmIG1ha2VfdGVzdF9vdXRwdXQoKToKICAgIHBhcnNlciA9IGNyZWF0ZV9wYXJzZXIoKQogICAgcmVzdWx0ID0gU3RyaW5nSU8oKQogICAgeG1sZ2VuID0gWE1MR2VuZXJhdG9yKHJlc3VsdCkKCiAgICBwYXJzZXIuc2V0Q29udGVudEhhbmRsZXIoeG1sZ2VuKQogICAgcGFyc2VyLnBhcnNlKGZpbmRmaWxlKCJ0ZXN0LnhtbCIpKQoKICAgIG91dGYgPSBvcGVuKGZpbmRmaWxlKCJ0ZXN0LnhtbC5vdXQiKSwgInciKQogICAgb3V0Zi53cml0ZShyZXN1bHQuZ2V0dmFsdWUoKSkKICAgIG91dGYuY2xvc2UoKQoKaXRlbXMgPSBsb2NhbHMoKS5pdGVtcygpCml0ZW1zLnNvcnQoKQpmb3IgKG5hbWUsIHZhbHVlKSBpbiBpdGVtczoKICAgIGlmIG5hbWVbIDogNV0gPT0gInRlc3RfIjoKICAgICAgICBjb25maXJtKHZhbHVlKCksIG5hbWUpCgpwcmludCAiJWQgdGVzdHMsICVkIGZhaWx1cmVzIiAlICh0ZXN0cywgZmFpbHMpCmlmIGZhaWxzICE9IDA6CiAgICByYWlzZSBUZXN0RmFpbGVkLCAiJWQgb2YgJWQgdGVzdHMgZmFpbGVkIiAlIChmYWlscywgdGVzdHMpCg==