I2luY2x1ZGUgPEFFRGF0YU1vZGVsLmg+CgojZGVmaW5lIERFQlVHIDAKCiNkZWZpbmUga0NvbXBvbmVudFNpZ25hdHVyZVN0cmluZyAiQkJQeS5MTSIgICAgICAgICAgICAgICAgIAojaW5jbHVkZSA8RGVidWdnaW5nLmg+CgoKI2luY2x1ZGUgPEJCTE1JbnRlcmZhY2UuaD4KI2luY2x1ZGUgPEJCWFRJbnRlcmZhY2UuaD4KLy8jaW5jbHVkZSA8QkJMTVRleHRJdGVyYXRvci5oPgoKI2luY2x1ZGUgPGN0eXBlLmg+CiNpbmNsdWRlIDxzdHJpbmcuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KCiNpbmNsdWRlIDxTb3VuZC5oPgoKI2lmIERFQlVHCnZvaWQgZGVidWdmXyhjb25zdCBjaGFyKiBmdW5jLGNvbnN0IGNoYXIqIGZpbGVOYW1lLGxvbmcgbGluZSwgY29uc3QgY2hhcipmbXQsLi4uKQp7Cgl2YV9saXN0IGFyZzsKCWNoYXIgbXNnWzI1Nl07Cgl2YV9zdGFydChhcmcsIGZtdCk7Cgl2c25wcmludGYobXNnLDI1NiAsZm10LCBhcmcpOwogICAgRGVidWdBc3NlcnQoQ09NUE9ORU5UX1NJR05BVFVSRSwgREVCVUdfTk9fT1BUSU9OUywga0NvbXBvbmVudFNpZ25hdHVyZVN0cmluZyAiOiAiICwgbXNnLCBuaWwsIGZpbGVOYW1lLCBsaW5lLCAwICk7CgoJLy9kZWJ1Z19zdHJpbmcobXNnKTsKfQojZGVmaW5lIGRlYnVnZihGTVQsLi4uKSAgZGVidWdmXyggX19GVU5DVElPTl9fLF9fRklMRV9fLCBfX0xJTkVfXyxGTVQsX19WQV9BUkdTX18pOwojZWxzZQojZGVmaW5lIGRlYnVnZihGTVQsLi4uKSAKI2VuZGlmCgp0eXBlZGVmIGNvbnN0IGNoYXIgKlN0cjsgCgoKZW51bXsKCWtQeUJCTE1TdHJpbmdTdWJzdCA9ICBrQkJMTUZpcnN0VXNlclJ1bktpbmQKfTsKCiNkZWZpbmUgaXN3b3JkY2hhcih4KSAoaXNhbG51bSh4KXx8eD09J18nKQoKCnN0cnVjdCBydW5sb2N7Cglib29sIHBhc3RfZ2FwOwoJbG9uZyBwb3M7Cglsb25nIGxhc3Rfc3RhcnQ7Cgl1bnNpZ25lZCBjaGFyKnA7Cn07CgpjaGFyIHN0YXJ0KHN0cnVjdCBydW5sb2MmIHIsQkJMTVBhcmFtQmxvY2sgJnBiKQp7CglyLnBhc3RfZ2FwID0gZmFsc2U7CglyLmxhc3Rfc3RhcnQgPSBwYi5mQ2FsY1J1blBhcmFtcy5mU3RhcnRPZmZzZXQ7CglyLnBvcyA9IHBiLmZDYWxjUnVuUGFyYW1zLmZTdGFydE9mZnNldDsKCXIucCA9ICgodW5zaWduZWQgY2hhciopcGIuZlRleHQpICsgcGIuZkNhbGNSdW5QYXJhbXMuZlN0YXJ0T2Zmc2V0OwoJLy8gQWRqdXN0IGZvciB0aGUgZ2FwIGlmIHdl1XJlIG5vdCBhbHJlYWR5IHBhc3QgaXQuCglpZiAoKCFyLnBhc3RfZ2FwKSAmJiAoci5wb3MgPj0gcGIuZlRleHRHYXBMb2NhdGlvbikpewoJCXIucCArPSBwYi5mVGV4dEdhcExlbmd0aDsKCQlyLnBhc3RfZ2FwID0gdHJ1ZTsKCX0KCXJldHVybiAqci5wOwoKfQoKY2hhciBuZXh0Y2hhcihzdHJ1Y3QgcnVubG9jJnIsQkJMTVBhcmFtQmxvY2sgJnBiKQp7CglpZiAoIHIucG9zPCBwYi5mVGV4dExlbmd0aCl7CgkJKytyLnBvczsKCQkrK3IucDsKCQlpZiAoKCFyLnBhc3RfZ2FwKSAmJiAoci5wb3MgPj0gcGIuZlRleHRHYXBMb2NhdGlvbikpewoJCQlyLnAgKz0gcGIuZlRleHRHYXBMZW5ndGg7CgkJCXIucGFzdF9nYXAgPSB0cnVlOwoJCX0KCQlyZXR1cm4gKnIucDsKCX0KCWVsc2V7CgkJcmV0dXJuIDA7Cgl9Cn0KCmJvb2wgYWRkUnVuKEJCTE1SdW5Db2RlIGtpbmQsIGludCAgc3RhcnQsaW50IGxlbiAsIGNvbnN0IEJCTE1DYWxsYmFja0Jsb2NrJiBiYmxtX2NhbGxiYWNrcykKewoJaWYgKGxlbiA+IDApeyAvLyBUaWUgb2ZmIHRoZSBjb2RlIHJ1biB3ZSB3ZXJlIGluLCB1bmxlc3MgdGhlIGxlbmd0aCBpcyB6ZXJvLgoJCWRlYnVnZigiUnVuICVkICVkOiVkIiwga2luZCwgc3RhcnQsIHN0YXJ0K2xlbi0xICk7CgkJcmV0dXJuIGJibG1BZGRSdW4oCSZiYmxtX2NhbGxiYWNrcywgJ1B5dGgnLAoJCQkJCQkJa2luZCwgc3RhcnQsIGxlbiwgZmFsc2UpOwoJCQkJCQkJCgl9CgllbHNlewoJCXJldHVybiB0cnVlOwoJfQp9CQkJCQkKCmJvb2wgYWRkUnVuQmVmb3JlIChCQkxNUnVuQ29kZSBraW5kLHN0cnVjdCBydW5sb2MmIHIsIGNvbnN0IEJCTE1DYWxsYmFja0Jsb2NrJiBiYmxtX2NhbGxiYWNrcykKewoJYm9vbCBtb3JlX3J1bnMgPSBhZGRSdW4oa2luZCwgci5sYXN0X3N0YXJ0LCByLnBvcyAtIHIubGFzdF9zdGFydCwgYmJsbV9jYWxsYmFja3MpOwoJci5sYXN0X3N0YXJ0ID0gIHIucG9zOwoJcmV0dXJuIG1vcmVfcnVuczsKfQoKYm9vbCBhZGRSdW5UbyAoQkJMTVJ1bkNvZGUga2luZCwgc3RydWN0IHJ1bmxvYyYgciwgY29uc3QgQkJMTUNhbGxiYWNrQmxvY2smIGJibG1fY2FsbGJhY2tzKQp7Cglib29sIG1vcmVfcnVucyA9IGFkZFJ1bihraW5kLCByLmxhc3Rfc3RhcnQsIHIucG9zIC0gci5sYXN0X3N0YXJ0KzEsIGJibG1fY2FsbGJhY2tzKTsKCXIubGFzdF9zdGFydCA9ICByLnBvcysxOwoJcmV0dXJuIG1vcmVfcnVuczsKfQoKCmJvb2wgY29sb3JzdHIoCWNoYXIgZGVsaW0sCgkJCQlCQkxNUGFyYW1CbG9jayAmcGIsCgkJCQlzdHJ1Y3QgcnVubG9jICZyLAoJCQkJY29uc3QgQkJMTUNhbGxiYWNrQmxvY2sgJmJibG1fY2FsbGJhY2tzKQp7Cglib29sIHRyaXBwbGUgPSBmYWxzZSAsIHBlcnMgPSBmYWxzZSwgbG9va3VwID0gZmFsc2UsIG1vcmVfcnVucyA9IHRydWU7CgljaGFyIGMgPSBuZXh0Y2hhcihyLHBiKTsKCglpZiAoYyA9PSBkZWxpbSl7CgkJYyA9IG5leHRjaGFyKHIscGIpOwoJCWlmIChjID09IGRlbGltKXsKCQkJdHJpcHBsZSA9IHRydWU7CgkJCWMgPSBuZXh0Y2hhcihyLHBiKTsKCQl9ICAKCQllbHNlewoJCQkvL2RvdWJsZQoJCQlyZXR1cm4gYWRkUnVuQmVmb3JlKGtCQkxNUnVuSXNTaW5nbGVTdHJpbmcscixiYmxtX2NhbGxiYWNrcyk7CgkJfQkKCX0KCXdoaWxlIChjICYmIG1vcmVfcnVucyl7CgkJaWYgKHBlcnMgKXsKCQkJaWYgKGlzYWxwaGEoYykpewoJCQkJbW9yZV9ydW5zID0gYWRkUnVuVG8oa1B5QkJMTVN0cmluZ1N1YnN0LHIsYmJsbV9jYWxsYmFja3MpOwoJCQl9CgkJCWVsc2UgaWYgKGMgPT0gJygnKXsKCQkJCWxvb2t1cCA9IHRydWU7CgkJCX0KCQl9CgkJcGVycyA9IGZhbHNlOwoJCWlmIChjID09IGRlbGltKXsKCQkJaWYgKHRyaXBwbGUpewoJCQkJaWYgKChjID0gbmV4dGNoYXIocixwYikpPT0gZGVsaW0gJiYgKGMgPSBuZXh0Y2hhcihyLHBiKSkgPT0gZGVsaW0pewoJCQkJCWJyZWFrOyAvLyBlbmQgb2YgdHJpcHBsZS1xdW90ZS4KCQkJCX0gIAoJCQl9CgkJCWVsc2V7CgkJCQlicmVhazsgLy8gZW5kIG9mIHNpbmdsZS1xdW90ZS4KCQkJfQoJCQkKCQl9CgkJZWxzZSBpZiAoYz09ICdcXCcpewoJCQluZXh0Y2hhcihyLHBiKTsKCQl9CgkJZWxzZSBpZiAoYz09J1xyJ3x8Yz09J1xuJyl7CgkJCWlmICghdHJpcHBsZSl7CQoJCQkJYnJlYWs7CgkJCX0KCQl9CgkJZWxzZSBpZiAoYz09JyUnKXsKCQkJbW9yZV9ydW5zID0gYWRkUnVuQmVmb3JlKGtCQkxNUnVuSXNTaW5nbGVTdHJpbmcscixiYmxtX2NhbGxiYWNrcyk7CgkJCXBlcnMgPSB0cnVlOwoJCX0KCQllbHNlIGlmIChjPT0nKScgJiYgbG9va3VwKXsKCQkJbW9yZV9ydW5zID0gYWRkUnVuVG8oa1B5QkJMTVN0cmluZ1N1YnN0LHIsYmJsbV9jYWxsYmFja3MpOwoJCQlsb29rdXAgPSBmYWxzZTsKCQl9CgkJYyA9IG5leHRjaGFyKHIscGIpOwoJfQoJcmV0dXJuIG1vcmVfcnVucyAmJiBhZGRSdW5Ubyhsb29rdXA/a1B5QkJMTVN0cmluZ1N1YnN0OmtCQkxNUnVuSXNTaW5nbGVTdHJpbmcscixiYmxtX2NhbGxiYWNrcyk7Cn0KCmJvb2wgY29sb3Jjb21tZW50KEJCTE1QYXJhbUJsb2NrICZwYiwKCQkJCXN0cnVjdCBydW5sb2MgJnIsCgkJCQljb25zdCBCQkxNQ2FsbGJhY2tCbG9jayAmYmJsbV9jYWxsYmFja3MpCnsKCXdoaWxlIChjaGFyIGMgPSBuZXh0Y2hhcihyLHBiKSl7CgkJaWYgKGM9PSdccid8fCBjPT0nXG4nKXsKCQkJYnJlYWs7CgkJfQoJfQoJcmV0dXJuIGFkZFJ1blRvKGtCQkxNUnVuSXNMaW5lQ29tbWVudCxyLGJibG1fY2FsbGJhY2tzKTsKfQoKdm9pZCBDYWxjdWxhdGVSdW5zKEJCTE1QYXJhbUJsb2NrICZwYiwKCQkJY29uc3QgQkJMTUNhbGxiYWNrQmxvY2sgJmJibG1fY2FsbGJhY2tzKQoKewoJY29uc3Qgc3RydWN0IHJ1bmRlc2MJKnN0YXRlID0gTlVMTDsKCWJvb2wgbW9yZV9ydW5zPXRydWU7CgkJCglzdHJ1Y3QgcnVubG9jIHI7CgkKCWNoYXIgYyA9IHN0YXJ0KHIscGIpOwoJCgl3aGlsZSAoYyAmJiBtb3JlX3J1bnMpewoJbG9vcDoKCQkvLyBQcm9jZXNzIGEgY2hhcgoJCWlmIChzdGF0ZT09TlVMTCl7CgkJCS8vSWYgd2UncmUgaW4gdGhlIGJhc2ljICdjb2RlJyBzdGF0ZSwgY2hlY2sgZm9yIGVhY2ggaW50ZXJlc3RpbmcgY2hhciAocnVuZGVsaW1zW2ldLnN0YXJ0KS4KCQkJc3dpdGNoIChjKXsKCQkJY2FzZSAnXCcnOgoJCQljYXNlICciJzogCgkJCQltb3JlX3J1bnMgPSBhZGRSdW5CZWZvcmUoa0JCTE1SdW5Jc0NvZGUscixiYmxtX2NhbGxiYWNrcyk7CgkJCQlpZiAobW9yZV9ydW5zKXsKCQkJCQltb3JlX3J1bnMgPSBjb2xvcnN0cihjLHBiLHIsYmJsbV9jYWxsYmFja3MpOwoJCQkJfQoJCQkJYnJlYWs7CgkJCWNhc2UgJyMnIDoKCQkJCW1vcmVfcnVucyA9IGFkZFJ1bkJlZm9yZShrQkJMTVJ1bklzQ29kZSxyLGJibG1fY2FsbGJhY2tzKTsKCQkJCWlmIChtb3JlX3J1bnMpewoJCQkJCW1vcmVfcnVucyA9IGNvbG9yY29tbWVudChwYixyLGJibG1fY2FsbGJhY2tzKTsgCgkJCQl9CgkJCQlicmVhazsKCQkJZGVmYXVsdDoKCQkJCWJyZWFrOwoJCQl9CgoJCX0KCQljID0gbmV4dGNoYXIocixwYik7Cgl9CglpZiAobW9yZV9ydW5zKXsKCQlhZGRSdW5CZWZvcmUoa0JCTE1SdW5Jc0NvZGUscixiYmxtX2NhbGxiYWNrcyk7Cgl9CgkKCn0Kc3RhdGljIHZvaWQgQWRqdXN0UmFuZ2UoQkJMTVBhcmFtQmxvY2sgJnBhcmFtcywKCQkJCQkJY29uc3QgQkJMTUNhbGxiYWNrQmxvY2sgJmNhbGxiYWNrcykKewkKCURlc2NUeXBlIGxhbmd1YWdlOwoJQkJMTVJ1bkNvZGUga2luZDsKCVNJbnQzMiBjaGFyUG9zOwoJU0ludDMyIGxlbmd0aDsKCVVJbnQzMiBpbmRleCA9IHBhcmFtcy5mQWRqdXN0UmFuZ2VQYXJhbXMuZlN0YXJ0SW5kZXg7CgkKCXdoaWxlKAlpbmRleCA+IDAgJiYKCQkJYmJsbUdldFJ1bigmY2FsbGJhY2tzLCBpbmRleCwgbGFuZ3VhZ2UsIGtpbmQsIGNoYXJQb3MsIGxlbmd0aCkgJiYKCQkgCShraW5kPT1rUHlCQkxNU3RyaW5nU3Vic3R8fGtpbmQ9PWtCQkxNUnVuSXNTaW5nbGVTdHJpbmcpKXsKCSAJaW5kZXgtLTsKCX07CgkgcGFyYW1zLmZBZGp1c3RSYW5nZVBhcmFtcy5mU3RhcnRJbmRleCA9IGluZGV4Owp9CgoKLy8gVGhlIG5leHQgY291cGxlIGZ1bmNzIHByb2Nlc3MgdGhlIHRleHQgb2YgYSBmaWxlIGFzc3VtbWluZyBpdCdzIGluIDEgcGllY2UgaW4gbWVtb3J5LAovLyBzbyB0aGV5IG1heSBub3QgYmUgY2FsbGVkIGZyb20gQ2FsY3VsYXRlUnVucy4KCmJvb2wgbWF0Y2h3b3JkKEJCTE1QYXJhbUJsb2NrICZwYiwgY29uc3QgY2hhciAqcGF0ICx1bnNpZ25lZCBsb25nICpwb3MpCnsJCgljb25zdCBjaGFyICphc2NpVGV4dCA9IChjb25zdCBjaGFyICopIChwYi5mVGV4dElzVW5pY29kZT9OVUxMOnBiLmZUZXh0KTsKCglpbnQgaTsKCWZvciAoaT0wOyBwYXRbaV07IGkrKyl7CgkJaWYgKCpwb3MraT49cGIuZlRleHRMZW5ndGgpewoJCQlyZXR1cm4gZmFsc2U7CgkJfQoJCWlmIChhc2NpVGV4dFsqcG9zK2ldICE9IHBhdFtpXSl7CgkJCXJldHVybiBmYWxzZTsKCQl9Cgl9CglpZiAoKCpwb3MraTxwYi5mVGV4dExlbmd0aCkmJmlzd29yZGNoYXIoYXNjaVRleHRbKnBvcytpXSkpewoJCXJldHVybiBmYWxzZTsKCX0KCSpwb3MrPWk7CglyZXR1cm4gdHJ1ZTsKfQkKCmludCBtYXRjaGluZGVudChCQkxNUGFyYW1CbG9jayAmcGIsIFVJbnQzMiAqcG9zKQp7CQoJY29uc3QgY2hhciAqYXNjaVRleHQgPSAoY29uc3QgY2hhciAqKSAocGIuZlRleHRJc1VuaWNvZGU/TlVMTDpwYi5mVGV4dCk7CglpbnQgaW5kZW50PTA7CgkJCgl3aGlsZSgqcG9zPHBiLmZUZXh0TGVuZ3RoKXsKCQlzd2l0Y2ggKC8qKGNoYXIpKHBiLmZUZXh0SXNVbmljb2RlP3VuaVRleHRbcG9zXToqL2FzY2lUZXh0Wypwb3NdLyopKi8pewoJCWNhc2UgJyAnOgoJCQkrKypwb3M7CgkJCWluZGVudCsrOwoJCQlicmVhazsJCgkJY2FzZSAnXHQnOgoJCQkrKypwb3M7CQkKCQkJaW5kZW50Kz04OwoJCQlicmVhazsKCQljYXNlICcjJzoKCQkJcmV0dXJuIC0xOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlyZXR1cm4gaW5kZW50OwoJCQlicmVhazsKCQl9Cgl9CQp9CgoKdm9pZCBlYXRfbGluZShCQkxNUGFyYW1CbG9jayAmcGIsIHVuc2lnbmVkIGxvbmcqIHBvcykKewoJY29uc3QgY2hhciAqYXNjaVRleHQgPSAoY29uc3QgY2hhciAqKSAocGIuZlRleHRJc1VuaWNvZGU/TlVMTDpwYi5mVGV4dCk7Cgl3aGlsZSAoYXNjaVRleHRbKnBvc10hPSdccicgJiYgYXNjaVRleHRbKnBvc10hPSdcbicgJiYgKnBvczxwYi5mVGV4dExlbmd0aCkgeysrKnBvczt9Cgl3aGlsZSAoKGFzY2lUZXh0Wypwb3NdPT0nXHInIHx8IGFzY2lUZXh0Wypwb3NdPT0nXG4nKSAmJiAqcG9zPHBiLmZUZXh0TGVuZ3RoKSB7KysqcG9zO30KCn0KCnZvaWQgYWRkSXRlbShCQkxNUGFyYW1CbG9jayAmcGIsIFVJbnQzMiBwb3MsIGludCBuZXN0LCBCQkxNRnVuY3Rpb25LaW5kcyBraW5kLAoJCQljb25zdCBCQkxNQ2FsbGJhY2tCbG9jayAqYmJsbV9jYWxsYmFja3MpCnsKCVVJbnQzMiBmdW5jc3RhcnRwb3MgPSBwb3M7CglVSW50MzIgZnVuY25hbWVsZW49MDsKCVVJbnQzMiBvZmZzZXQ9MDsKCWNvbnN0IGNoYXIgKmFzY2lUZXh0ID0gKGNvbnN0IGNoYXIgKikgcGIuZlRleHQ7CglVSW50MzIgaW5kZXg7CglPU0VyciBlcnI7CgkKCXdoaWxlIChpc3NwYWNlKGFzY2lUZXh0W3Bvc10pICYmIHBvczxwYi5mVGV4dExlbmd0aCkgeysrcG9zO30KCVVJbnQzMiBmbmFtZXN0YXJ0ID0gcG9zOwoJd2hpbGUgKChpc2FsbnVtKGFzY2lUZXh0W3Bvc10pfHxhc2NpVGV4dFtwb3NdPT0nXycpICYmIHBvczxwYi5mVGV4dExlbmd0aCkge3BvcysrOyBmdW5jbmFtZWxlbisrO30KCQoJZXJyID0gYmJsbUFkZFRva2VuVG9CdWZmZXIoCWJibG1fY2FsbGJhY2tzLCAKCQkJCQkJCQlwYi5mRmNuUGFyYW1zLmZUb2tlbkJ1ZmZlciwKCQkJCQkJCQkodm9pZCopJmFzY2lUZXh0W2ZuYW1lc3RhcnRdLAoJCQkJCQkJCWZ1bmNuYW1lbGVuLAoJCQkJCQkJCXBiLmZUZXh0SXNVbmljb2RlLAoJCQkJCQkJCSZvZmZzZXQpOwoJQkJMTVByb2NJbmZvIHByb2NJbmZvOyAKCXByb2NJbmZvLmZGdW5jdGlvblN0YXJ0ID0gZm5hbWVzdGFydDsJLy8JY2hhciBvZmZzZXQgaW4gZmlsZSBvZiBmaXJzdCBjaGFyYWN0ZXIgb2YgZnVuY3Rpb24KCXByb2NJbmZvLmZGdW5jdGlvbkVuZCA9IHBvczsJLy8JY2hhciBvZmZzZXQgb2YgbGFzdCBjaGFyYWN0ZXIgb2YgZnVuY3Rpb24KCQoJcHJvY0luZm8uZlNlbFN0YXJ0ID0gZm5hbWVzdGFydDsJCS8vCWZpcnN0IGNoYXJhY3RlciB0byBzZWxlY3Qgd2hlbiBjaG9vc2luZyBmdW5jdGlvbgoJcHJvY0luZm8uZlNlbEVuZCA9IHBvczsJCS8vCWxhc3QgY2hhcmFjdGVyIHRvIHNlbGVjdCB3aGVuIGNob29zaW5nIGZ1bmN0aW9uCgkKCXByb2NJbmZvLmZGaXJzdENoYXIgPSBmbmFtZXN0YXJ0OwkJLy8JZmlyc3QgY2hhcmFjdGVyIHRvIG1ha2UgdmlzaWJsZSB3aGVuIGNob29zaW5nIGZ1bmN0aW9uCgkKCXByb2NJbmZvLmZLaW5kID0ga2luZDsKCQoJcHJvY0luZm8uZkluZGVudExldmVsID0gbmVzdDsJLy8JaW5kZW50YXRpb24gbGV2ZWwgb2YgdG9rZW4KCXByb2NJbmZvLmZGbGFncyA9IDA7CQkJLy8JdG9rZW4gZmxhZ3MgKHNlZSBCQkxNRnVuY3Rpb25GbGFncykKCXByb2NJbmZvLmZOYW1lU3RhcnQgPSBvZmZzZXQ7CQkvLwljaGFyIG9mZnNldCBpbiB0b2tlbiBidWZmZXIgb2YgdG9rZW4gbmFtZQoJcHJvY0luZm8uZk5hbWVMZW5ndGggPSBmdW5jbmFtZWxlbjsJLy8JbGVuZ3RoIG9mIHRva2VuIG5hbWUKCQkJCQkJCQkJCQkJCQkJCQoJZXJyID0gYmJsbUFkZEZ1bmN0aW9uVG9MaXN0KGJibG1fY2FsbGJhY2tzLAkKCQkJCQkJCQlwYi5mRmNuUGFyYW1zLmZGY25MaXN0LAoJCQkJCQkJCXByb2NJbmZvLAoJCQkJCQkJCSZpbmRleCk7Cn0KCgoKZW51bXsKCW1heG5lc3Q9NQp9OwoKdm9pZCBTY2FuRm9yRnVuY3Rpb25zKEJCTE1QYXJhbUJsb2NrICZwYiwKCQkJY29uc3QgQkJMTUNhbGxiYWNrQmxvY2sgJmJibG1fY2FsbGJhY2tzKQp7CgoJY29uc3QgY2hhciAqYXNjaVRleHQgPSAoY29uc3QgY2hhciAqKSAocGIuZlRleHRJc1VuaWNvZGU/TlVMTDpwYi5mVGV4dCk7CglVbmlDaGFyUHRyIHVuaVRleHQgPSAoVW5pQ2hhclB0cikgKHBiLmZUZXh0SXNVbmljb2RlP3BiLmZUZXh0Ok5VTEwpOwoJCglpbnQgaW5kZW50c1ttYXhuZXN0XT0gezB9OwoJaW50IG5lc3QgPSAwOwoJCglVSW50MzIgcG9zPTA7IC8vIGN1cnJlbnQgY2hhcmFjdGVyIG9mZnNldAoKCQoJd2hpbGUgKHBvczxwYi5mVGV4dExlbmd0aCl7CgkJCgkJaW50IGluZGVudCA9IG1hdGNoaW5kZW50KHBiLCAmcG9zKTsKCQkKCQlpZiAoaW5kZW50ID49IDApewoJCQlmb3IgKGludCBpPTA7IGkgPD0gbmVzdDsgaSsrKXsKCQkJCWlmIChpbmRlbnQ8PWluZGVudHNbaV0pewoJCQkJCW5lc3QgPSBpOwoJCQkJCWluZGVudHNbbmVzdF09aW5kZW50OwoJCQkJCWdvdG8geDsKCQkJCX0KCQkJfQoJCQlpbmRlbnRzWysrbmVzdF09aW5kZW50OwoJCQl4OgoJCQoJCQlpZiAobWF0Y2h3b3JkKHBiLCJkZWYiLCZwb3MpKXsKCQkJCWFkZEl0ZW0oIHBiLCBwb3MsIG5lc3QsIGtCQkxNRnVuY3Rpb25NYXJrLCAmYmJsbV9jYWxsYmFja3MpOwoJCQl9CgkJCWVsc2UgaWYgKG1hdGNod29yZChwYiwgImNsYXNzIiwgJnBvcykpewoJCQkJYWRkSXRlbSggcGIsIHBvcywgbmVzdCwga0JCTE1UeXBlZGVmLCAmYmJsbV9jYWxsYmFja3MpOwoJCQl9CgkJfQoJCWVhdF9saW5lKHBiLCZwb3MpOwoJfQoJCn0KCk9TRXJyIG1haW4oCUJCTE1QYXJhbUJsb2NrICZwYXJhbXMsCgkJCWNvbnN0IEJCTE1DYWxsYmFja0Jsb2NrICZiYmxtX2NhbGxiYWNrcywKCQkJY29uc3QgQkJYVENhbGxiYWNrQmxvY2sgJmJieHRfY2FsbGJhY2tzKQp7CglPU0VyciByZXN1bHQ7CgoJaWYgKChwYXJhbXMuZlNpZ25hdHVyZSAhPSBrQkJMTVBhcmFtQmxvY2tTaWduYXR1cmUpIHx8CgkJKHBhcmFtcy5mTGVuZ3RoIDwgc2l6ZW9mKEJCTE1QYXJhbUJsb2NrKSkpCgl7CgkJcmV0dXJuIHBhcmFtRXJyOwoJfQoJCglzd2l0Y2ggKHBhcmFtcy5mTWVzc2FnZSkKCXsKCQljYXNlIGtCQkxNSW5pdE1lc3NhZ2U6CgkJY2FzZSBrQkJMTURpc3Bvc2VNZXNzYWdlOgoJCXsKCQkJcmVzdWx0ID0gbm9FcnI7CS8vIG5vdGhpbmcgdG8gZG8KCQkJYnJlYWs7CgkJfQoJCQoJCWNhc2Uga0JCTE1DYWxjdWxhdGVSdW5zTWVzc2FnZToKCQkJQ2FsY3VsYXRlUnVucyhwYXJhbXMsIGJibG1fY2FsbGJhY2tzKTsKCQkJcmVzdWx0ID0gbm9FcnI7CgkJCWJyZWFrOwoKCQljYXNlIGtCQkxNU2NhbkZvckZ1bmN0aW9uc01lc3NhZ2U6CgkJCVNjYW5Gb3JGdW5jdGlvbnMocGFyYW1zLCBiYmxtX2NhbGxiYWNrcyk7CgkJCXJlc3VsdCA9IG5vRXJyOwoJCQlicmVhazsKCgkJY2FzZSBrQkJMTUFkanVzdFJhbmdlTWVzc2FnZToKCQkJQWRqdXN0UmFuZ2UocGFyYW1zLCBiYmxtX2NhbGxiYWNrcyk7CgkJCXJlc3VsdCA9IG5vRXJyOwoJCQlicmVhazsKCQkKCQljYXNlIGtCQkxNTWFwUnVuS2luZFRvQ29sb3JDb2RlTWVzc2FnZToKCQkJc3dpdGNoIChwYXJhbXMuZk1hcFJ1blBhcmFtcy5mUnVuS2luZCl7CgkJCWNhc2Uga1B5QkJMTVN0cmluZ1N1YnN0OgoJCQkJcGFyYW1zLmZNYXBSdW5QYXJhbXMuZkNvbG9yQ29kZSA9IGtCQkxNU0dNTEF0dHJpYnV0ZU5hbWVDb2xvcjsKCQkJCXBhcmFtcy5mTWFwUnVuUGFyYW1zLmZNYXBwZWQgPQl0cnVlOwoJCQkJYnJlYWs7CQoJCQlkZWZhdWx0OgoJCQkJcGFyYW1zLmZNYXBSdW5QYXJhbXMuZk1hcHBlZCA9CWZhbHNlOwoJCQl9CgkJCXJlc3VsdCA9IG5vRXJyOwoJCQlicmVhazsKCgkJY2FzZSBrQkJMTUVzY2FwZVN0cmluZ01lc3NhZ2U6CgkJY2FzZSBrQkJMTUFkanVzdEVuZE1lc3NhZ2U6CgkJY2FzZSBrQkJMTU1hcENvbG9yQ29kZVRvQ29sb3JNZXNzYWdlOgoJCWNhc2Uga0JCTE1TZXRDYXRlZ29yaWVzTWVzc2FnZToKCQljYXNlIGtCQkxNTWF0Y2hLZXl3b3JkTWVzc2FnZToKCQl7CgkJCXJlc3VsdCA9IHVzZXJDYW5jZWxlZEVycjsKCQkJYnJlYWs7CgkJfQoJCQkKCQlkZWZhdWx0OgoJCXsKCQkJcmVzdWx0ID0gcGFyYW1FcnI7CgkJCWJyZWFrOwoJCX0KCX0KCXJldHVybiByZXN1bHQ7CQp9